Nifty Cloud Mobile Backendのデータストア・基本編
Nifty Cloud Mobile Backendでいろいろやってみようシリーズ、第4弾(?)
今回は、データストアの基本的な使い方を調べてみました。具体的には、オブジェクトのサブクラス化・保存・読み込み・更新・削除などです。
とりあえず、ソースコードを公開してあるので、よくわからない部分は直接見てもらった方が早いでしょう。たぶん。
See_Ku / NcmbDatastoreDemo — Bitbucket
https://bitbucket.org/See_Ku/ncmbdatastoredemo
実際に動かすと、こんな画面になります。
動作を確認した環境
環境 | 情報 |
---|---|
Xcode | 7.2.1 (7C1002) |
iOS | 9.2 |
Swift | 2.1.1 |
Date | 2016/2/18 |
NCMB SDK | 2.2.5 |
オブジェクトのサブクラス化
簡単に言うと、NCMBObjectを継承したクラスを作ることで、普通のSwiftのクラスっぽくデータを使えるようにする方法です。
今回のデモではこんな感じにしてあります。
import NCMB @objc(StoreData) class StoreData: NCMBObject, NCMBSubclassing { // ///////////////////////////////////////////////////////////// // MARK: - NCMBSubclassing /// mobile backend上のクラス名を返却する static func ncmbClassName() -> String! { return "StoreData" } // ///////////////////////////////////////////////////////////// // MARK: - property /// 文字列型のプロパティ var name: String! { get { if let str = objectForKey("name") as? String { return str } else { return "" } } set { setObject(newValue, forKey: "name") } } /// 数値型のプロパティ var number: Int { get { if let num = objectForKey("number") as? NSNumber { return num.integerValue } else { return 0 } } set { setObject(NSNumber(integer: newValue), forKey: "number") } } }
ポイントをまとめるとしたらこんな感じでしょうか?
- @objcで内部のクラス名をObjective-Cの形式にあわせる必要がある
- NCMBObjectの継承とNCMBSubclassingの適応が必要
- ncmbClassName()でクラス名を返す必要がある
- Swiftのプロパティのget/setで値への操作を隠蔽
この他に、AppDelegateでクラスを登録する処理も必要になります。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // サブクラス化したNCMB向けクラスを登録 StoreData.registerSubclass() 以下略
全体的に、あまりSwiftっぽく無いのが残念ポイントですね。いろいろと努力すればもう少しマシになりますが、今回はデータストアのデモということで止めておきました。
データストアへオブジェクトを保存
オブジェクトを保存する部分はこんな感じになります。
/// 新しいデータを作成 func createData() { // 新しいデータを作成 let data = StoreData.object() as! StoreData data.name = "---" data.number = 0 // 非同期で保存 data.saveInBackgroundWithBlock() { error in if let error = error { print("create error: \(error)") return } print("create ok: ") // 画面を更新 let main = dispatch_get_main_queue() dispatch_async(main) { self.readDataSync() self.tableView.reloadData() } } }
新しくデータを入れたオブジェクトを作って、非同期で保存してるだけです。簡単ですね。
データを作成する部分がSwiftっぽく無いですが(以下略)
データストアからオブジェクトを読み込み(検索)
データを読み込む部分はこんな感じになりました。
var dataArray: [StoreData]? /// データを読み込み ※同期処理 func readDataSync() { let query = StoreData.query() query.limit = 20 do { dataArray = try query.findObjects() as? [StoreData] print("read ok: \(dataArray?.count)") } catch { print("read error: \(error)") dataArray = nil } }
Nifty Cloud Mobile Backendのサイトのサンプルを参考にしたため、ここは同期処理になってます。本来なら、非同期にするべきでしょう。
データストアのオブジェクトを更新
データの更新は保存と同じ処理ですね。
/// データを更新 func updateData() { guard let data = editData else { return } // 非同期で保存(更新) data.saveInBackgroundWithBlock() { error in if let error = error { print("update error: \(error)") } else { print("update ok: ") } } }
先頭で編集したデータを取り出して、後は保存してるだけです。objectIdが設定済みのオブジェクトを保存すれば、自動的に更新になる、と。
データストアのオブジェクトを削除
データの削除は更新とよく似てます。
/// データを削除 func deleteData() { guard let data = editData else { return } // 非同期で削除 data.deleteInBackgroundWithBlock() { error in if let error = error { print("delete error: \(error)") } else { print("delete ok: ") self.editData = nil self.configureView() } } }
objectIdが設定済みのオブジェクトに対して、削除を実行してるだけです。簡単ですね。
感想
いわゆるCRUDっぽい事をやるだけであれば、特に悩むこともなく実現可能でした。
どちらかというと、端々に表れるSwiftっぽく無い処理をどうするかの方が課題になるのかもしれません。