0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NCMBのSwift SDKを使って日報アプリを作る(その2:日報データの保存)

Posted at

NCMBのSwift SDKを使ってデモアプリを作ってみます。今回は業務系でよくあるニーズの日報アプリを作ってみます。実際にはデータストアやファイルストアを使うので、応用すれば汎用的に使えるはずです。

前回は画面の説明とSDKの導入まで行いましたので、今回は日報データの保存処理を作成します。

コードについて

今回のコードはNCMBMania/swift_daily_reportにアップロードしてあります。実装時の参考にしてください。

InputViewについて

日報の入力と保存はInputViewにて行います。画面は日報の日付、内容、そして写真選択といったフォームを表示しているのみです。

import SwiftUI
import NCMB

struct InputView: View {
    @State private var date = Date()     // 日報の日付
    @State private var text = ""         // 日報の本文
    @State private var showAlert = false // アラート表示用のフラグ
    @State private var message = ""      // アラートのメッセージ
    
    @State var imageData : Data = .init(capacity:0) // // 選択された写真データ
    @State var source:UIImagePickerController.SourceType = .photoLibrary // カメラまたはフォトライブラリ
    @State var isImagePicker = false // 写真ピッカーを表示する際のフラグ
    
    var body: some View {
        NavigationView {
            VStack(spacing: 10) {
                // 画像モーダルへの遷移用
                NavigationLink(
                    destination: Imagepicker(
                        show: $isImagePicker,
                        image: $imageData,
                        sourceType: source
                    ),
                    isActive:$isImagePicker,
                    label: {
                        Text("")
                    })
                // 日報の日付を選択
                DatePicker("日付",
                    selection: $date,
                    displayedComponents: .date
                )
                // 日報の内容を記述するTextEditor
                TextEditor(text: $text)
                    .frame(width: UIScreen.main.bounds.width * 0.8, height: 200)
                    .overlay(
                        RoundedRectangle(cornerRadius: 5)
                            .stroke(Color.blue, lineWidth: 2)
                    )
                // 画像が指定されれば、サムネイル表示
                if imageData.count != 0 {
                    Image(uiImage: UIImage(data: self.imageData)!)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(height: 100)
                        .cornerRadius(15)
                        .padding()
                }
                // 写真選択モーダルの表示
                Button(action: {
                    self.source = .photoLibrary
                    self.isImagePicker.toggle()
                }, label: {
                    Text("写真を選択")
                })
            }
            .navigationBarTitle("日報入力", displayMode: .inline)
            .toolbar {
                // 右上のアイコンで保存しょりを実行
                ToolbarItem(placement: .navigationBarTrailing){
                    Button(action: {
                        save()
                    }) {
                        Image(systemName: "icloud.and.arrow.up")
                    }
                }
            }
        }
        .alert(isPresented: $showAlert) {
            Alert(title: Text(self.message))
        }
    }
    
    // 日報を保存する処理
    func save() {
    }
}

Simulator Screen Shot - iPod touch (7th generation) - 2021-10-06 at 14.57.17.png

保存処理について

データの保存は save 関数にて行います。ここからはsave関数の内容について解説します。まずNCMBObject(DBでいう行相当)を準備します。クラス名というのは、DBでいうテーブル名相当です。

// DailyReportクラス(DBでいうテーブル相当)のインスタンス(DBでいう行相当)を準備
let obj = NCMBObject(className: "DailyReport")

この obj にキーを指定して、text(日報の本文)とdate(日報の日付)を指定します。これはDBでいうカラム相当になります。

// 指定されている値をセット
obj["text"] = self.text
obj["date"] = self.date

次に画像が指定されているかどうかを判定します。画像が指定されている場合には、そのデータをファイルストアに保存します。ファイル名はUUIDを使ってユニークなものにしています。

saveメソッドは同期的にファイル保存を行います。非同期処理が良い場合には saveInBackground も用意しています。必要に応じて使い分けてください。写真の保存処理がうまくいったら、そのファイル名をobjのfileNameキーに紐付けます。

// 画像があるか判断
if self.imageData.count > 0 {
    // 画像があれば、ファイルストアへ保存する
    // ファイル名はUUIDで生成
    let fileName = "\(UUID()).jpg"
    // ファイルストアのインスタンスを準備
    let file = NCMBFile(fileName: fileName)
    // 保存(ファイルストアへのアップロード)
    _ = file.save(data: self.imageData)
    // ファイル名をDailyReportクラスのインスタンスに紐付ける
    obj["fileName"] = fileName
}

そしてobjも保存します。

// データを保存(データストアにアップロード)
let result = obj.save()

こちらは処理判定を行っています。resultが .success(処理成功)か .failure(処理失敗)によって処理内容を変えています。最終的にアラートを出して処理完了です。

// 結果を判定
switch result {
case .success(): // 保存がうまくいったら、入力内容をリセット
    self.text = ""
    self.imageData.count = 0
    self.date = Date()
    // メッセージを設定
    self.message = "保存しました"
    break
case let .failure(err): // エラーの場合はエラーメッセージをセット
    self.message = err.localizedDescription
    break
}
// アラートを表示
self.showAlert = true

Simulator Screen Shot - iPod touch (7th generation) - 2021-10-06 at 14.59.08.png

ここまでで日報データの保存処理が完成となります。

まとめ

今回は日報アプリにおける日報データの保存処理を解説しました。次は日報データの検索と一覧表示周りを解説します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?