ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

NCMBのレスポンス結果を画面に反映する際に注意したいこと

f:id:mbaasdevrel:20180806093819p:plain

Swift SDKのTipsです。mBaaSへのアクセスはほぼすべてネットワークが伴う処理で、非同期になります。非同期処理はバックグラウンドで処理しますが、その結果をそのままSwift UIで画面表示に反映すると、次のような警告が表示されます。

Publishing changes from background threads is not allowed;
make sure to publish values from the main thread
(via operators like receive(on:)) on model updates.

今回はこの警告を消すための方法について紹介します。

サンプルコード

上記の警告が出るコードです。

@ObservedObject var Todo = Todos()
var body: some View {
    NavigationView {
        ZStack(alignment: .bottomTrailing) {
          // 省略
        }
        .onAppear {
            let query : NCMBQuery<NCMBObject> = NCMBQuery.getQuery(className: "Todo")
            query.findInBackground(callback: { result in
                switch result {
                    case let .success(array):
                        self.Todo.todos = array // ここで警告が表示される
                    case let .failure(error):
                        print("取得に失敗しました: \(error)")
                }
            })
        }
        // 省略
    }
}

回避策1

回避策として、非同期処理を同期にする方法があります。

let query : NCMBQuery<NCMBObject> = NCMBQuery.getQuery(className: "Todo")
let result = query.find()
switch result {
    case let .success(array):
        self.Todo.todos = array
    case let .failure(error):
        print("取得に失敗しました: \(error)")
}

これでもエラーは出ませんが、ネットワーク処理中は画面が固まってしまうという問題があります。UXとしてお勧めできません。

回避策2

回避策2は画面を書き換える処理だけメインスレッドに戻ってくるという方法です。具体的にいうと DispatchQueue.main.async で処理を囲みます。

let query : NCMBQuery<NCMBObject> = NCMBQuery.getQuery(className: "Todo")
query.findInBackground(callback: { result in
    switch result {
        case let .success(array):
            DispatchQueue.main.async {
                self.Todo.todos = array
            }
        case let .failure(error):
            print("取得に失敗しました: \(error)")
    }
})

これで画面を書き換える処理はメインスレッドで実行されるようになります。

まとめ

ネットワーク処理が伴うと非同期と同期を使い分ける必要が出ます。スレッドは目に見える訳ではないので分かりづらいでしょう。Swift6ではasync/awaitが実装されるという話なので、この方法ではなくなるかも知れませんが、現状はこのTipsをご利用ください。

中津川 篤司

中津川 篤司

NCMBエヴァンジェリスト。プログラマ、エンジニアとしていくつかの企業で働き、28歳のときに独立。 2004年、まだ情報が少なかったオープンソースソフトの技術ブログ「MOONGIFT」を開設し、毎日情報を発信している。2013年に法人化、ビジネスとエンジニアを結ぶDXエージェンシー「DevRel」活動をスタート。