LoginSignup
1

More than 1 year has passed since last update.

NCMBのSwift SDKを使って掲示板アプリを作る(その2:スレッドの作成と一覧表示)

Posted at

ニフクラ mobile backend(NCMB)では各種言語向けにSDKを提供しています。その中で最も新しいSwift SDKについて、その使い方を紹介します。

この記事では複数回に分けて、掲示板アプリを作ってみます。Swift SDKの使い方はもちろん、NCMBの基本的な利用法を学ぶのに役立ててください。前回は画面の説明と匿名認証の実装を行いましたので、今回はスレッドの作成と一覧表示を作成していきます。

なお、今回のコードはNCMBMania/Swift_Forum_Demo: Swift SDKで作る掲示板アプリのデモコードですにアップしてあります。

スレッド一覧画面について

ScreenShot_ 2021-08-06 18.36.10.png

前回も紹介しましたが、再度スレッド一覧画面 ThreadListView を紹介します。この画面で、プラスアイコンをタップすると AddThreadView が表示されます。

struct ThreadListView: View {
    @State var threads: [NCMBObject] = []
    @State private var showModal = false
    @State private var showAlert = false

    var body: some View {
        NavigationView {
            ZStack(alignment: .bottomTrailing) {
                List {
                    ForEach(self.threads, id: \.objectId) { thread in
                        NavigationLink(
                            destination: ThreadView(thread: thread)
                        ) {
                            ThreadListRow(thread: thread)
                        }
                    }
                    .onDelete(perform: delete)
                }
                .navigationBarTitle("掲示板", displayMode: .inline)
                .navigationBarItems(trailing:
                                        Button(action: {
                                            showModal.toggle()
                                        }, label: {
                                            Image(systemName: "plus")
                                                .resizable()
                                                .padding(6)
                                                .frame(width: 24, height: 24)
                                                .foregroundColor(.blue)
                                        })
                )
            }
        }
        .onAppear {
            getThread()
        }
        .sheet(isPresented: $showModal, content: {
            AddThreadView()
        })
        .onChange(of: showModal, perform: { value in
            if (!showModal) {
                getThread()
            }
        })
        .alert(isPresented: $showAlert, content: {
            Alert(title: Text("削除に失敗しました。権限がないようです。"))
        })
    }
}

AddThreadView の内容は次のようになっています。スレッドのタイトル、説明、そして画像を追加できるようになっています。情報を入力してスレッド追加ボタンをタップすると add 関数が呼ばれます。

ScreenShot_ 2021-08-06 18.36.48.png

struct AddThreadView: View {
    @Environment(\.presentationMode) private var presentationMode
    @State private var title = ""
    @State private var description = ""
    @State var showingPicker = false
    @State var image: UIImage?
    var body: some View {
        VStack {
            NavigationView {
                Form {
                    TextField("スレッドのタイトルを入力してください", text: $title)
                    TextField("スレッドの紹介文を入力してください", text: $description)
                    Button(action: {
                        showingPicker.toggle()
                    }) {
                        Text("画像追加")
                    }
                    if let image = image {
                        Image(uiImage: image)
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                    }
                    Button(action: {
                        add()
                    }) {
                        Text("スレッド追加")
                    }
                }
            }
        }
        .sheet(isPresented: $showingPicker) {
            ImagePickerView(image: $image, sourceType: .library)
        }
    }
}

add関数について

add関数の内容です。詳細はコメントを参考にしてください。

func add() {
    // スレッドクラスのNCMBObjectを作成
    let thread = NCMBObject(className: "Thread")
    // スレッドのタイトルと説明をセット
    thread["title"] = title
    thread["description"] = description
    // ACL(アクセス権限)を作成
    let user = NCMBUser.currentUser // ログインユーザの取得
    var acl = NCMBACL.empty
    // 誰でも読み込み可能、削除不可
    acl.put(key: "*", readable: true, writable: false)
    // 作成したユーザは読み書き可能
    acl.put(key: user!.objectId!, readable: true, writable: true)
    // ACLをセット
    thread.acl = acl
    // 画像が指定されている場合
    if let image = image {
        // ファイル名はUUIDでユニークなもの
        let uuid = UUID()
        // ファイル名
        let fileName = "\(uuid).jpg"
        // ファイルストアのオブジェクトを作成
        let photo = NCMBFile(fileName: fileName, acl: acl)
        // JPEGとしてデータを保存
        _ = photo.save(data: image.jpegData(compressionQuality: 80.0)!)
        // 保存したファイル名をNCMBObjectにセット
        thread["fileName"] = fileName
    }
    // 保存
    let results = thread.save()
    // 処理が成功したらモーダルを閉じる
    if case .success(_) = results {
        presentationMode.wrappedValue.dismiss()
    } else {
        print("Error")
    }
}

スレッド一覧の取得

ScreenShot_ 2021-08-07 11.31.37.png

スレッド一覧の取得は ThreadListViewgetThread 関数になります。こちらも実装はコメントを参照してください。

func getThread() {
    // スレッドクラスのNCMBQueryを準備
    let query = NCMBQuery.getQuery(className: "Thread")
    // 取得
    let results = query.find()
    switch results {
    case let .success(ary): // 取得成功した場合
        threads = ary // スレッドに適用
    case .failure(_): break
    }
}

これでスレッドを登録し、一覧表示まで行われるようになります。

スレッドの削除

ScreenShot_ 2021-08-07 16.45.30.png

スレッドはリストを左にスワイプすると、削除できるようになります。この時呼ばれるのは ThreadListViewdelete メソッドです。

func delete(at offsets: IndexSet) {
    // 処理対象のスレッドを取得
    let thread = self.threads[Array(offsets)[0]] as NCMBObject
    // 削除処理実行
    let results = thread.delete()
    // 処理結果の判定
    switch results {
    case .success(_): // 処理がうまくいったらスレッドを取り直し
        getThread()
    case .failure(_): // 処理が失敗したらアラートを出す
        showAlert = true
    }
}

処理が失敗した場合には alert を使ってアラート表示していています。自分に削除権限がない場合(自分が立てたスレッドでない場合)、削除は失敗します。

.alert(isPresented: $showAlert, content: {
    Alert(title: Text("削除に失敗しました。権限がないようです。"))
})

まとめ

今回は掲示板アプリのスレッド追加と一覧表示、削除について実装を行いました。次回はスレッドの詳細表示とコメントの追加、表示、削除を実装します。

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
What you can do with signing up
1