4. チュートリアル1 : TODOアプリ (Swift版)¶
本チュートリアルは、チュートリアル1(Objective-C)版と全く同じですが、 実装を Objective-C ではなく Swift で行っています。
BaaSサーバ側の設定手順は Objective-C 版と同じため割愛します。
4.1. サンプルコードの変更と実行¶
チュートリアル1(Swift)のサンプルコードを設定し、動作させてみます。
Xcode から tutorial1-swift ディレクトリを開いてください。
NebulaTutorial1/Config.swift ファイルを修正します。
// テナントID
let TENANT_ID = ""
// アプリケーションID
let APP_ID = ""
// アプリケーションキー
let APP_KEY = ""
// エンドポイント URI
let ENDPOINT_URI = "https://baas.example.com/api/";
テナントID, アプリケーションID/キー, エンドポイントURIを指定します。 内容は Objective-C 版と同じです。 変更が完了したら、ビルド・実行してください。
以下、実装手順について説明します。
4.2. NEC BaaS SDK Framework の追加¶
NEC BaaS iOS SDK を利用するためには、アプリケーションに Nebula SDK Framework を追加する必要があります。この手順は Objective-C 版と同じです。
4.3. ヘッダファイルの import¶
iOS SDK を使用するソースファイルは、適宜 nebulaIosSdk/Nebula.h ファイルを import する必要があります。 Swift を使用するプロジェクトでは、Bridging ヘッダ(プロジェクト名-Bridging-Header.h)に以下の1行を追加します。
#import "nebulaIosSdk/Nebula.h"
4.4. AppDelegate クラス¶
AppDelegate クラスの application() メソッド内で、 iOS SDK の初期化処理を行います。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject:AnyObject]?) -> Bool {
// Nebula 初期化処理
NBCore.setUpWithAppId(APP_ID, appKey: APP_KEY, tenantId: TENANT_ID);
NBCore.setEndPointUri(ENDPOINT_URI);
return true;
}
SDK の初期化には NBCore クラスを使用します。 setupWithAppId() を使用して以下のパラメータを設定します。
- テナントID
- アプリケーションID
- アプリケーションキー
また、setEndPointUri() を使用して、エンドポイントURIを設定します。
4.5. TodoListViewController クラス¶
アプリケーション本体は TodoListViewController クラスに実装します。 本クラスは UITableViewController を継承しており、Todo を Table View で表示します。
4.5.1. 初期化 (viewDidLoad)¶
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "TodoCell")
reloadTodos(nil)
}
初期化は viewDidLoad で行います。
ここでは reloadTodos() を呼び出し、Todo 一覧の取得を開始しています。
4.5.2. Todo 一覧の取得¶
// Todo 一覧を取得する
@IBAction func reloadTodos(sender: UIButton?) {
// バケット取得
var bucket = NBObjectBucket(bucketName: BUCKET_NAME)
// クエリ生成
var query = NBQuery()
query.setSortOrderWithKey("updatedAt", isAscend: true)
// クエリ実行
bucket.queryInBackgroundWithQuery(query, block: {objects, count, error in
self.hideIndicator()
if (error == nil) {
self.todos = objects as [NBObject];
self.tableView.reloadData()
} else {
NSLog("query error: %@", error)
}
})
showIndicator()
}
reloadTodos() で、サーバから Todo データの一覧を取得します。
最初にオブジェクトバケットのインスタンスを取得します。オブジェクトバケットは NBObjectBucket クラスの インスタンスとして作成し、コンストラクタでバケット名をセットします。
Todo データは、NBObjectBucket に対して queryInBackgroundWithQuery() を呼び出すことで取得できます。 クエリ(取得条件)は NBQuery クラスのインスタンスとして作成します。 ここでは更新日時(updatedAt)フィールド昇順で、全件取得するというクエリを作成しています。
処理が完了すると、block: 引数に指定したクロージャが呼び出されます。 正常時は objects にオブジェクトの一覧が、error に nil が格納されます。 ここでは todos プロパティに objects を保存し、tableView の reloadData を呼び出して画面描画を行います。
4.5.3. 画面描画¶
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return todos.count;
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
tableView.dequeueReusableCellWithIdentifier("TodoCell");
var cell = tableView.dequeueReusableCellWithIdentifier("TodoCell") as UITableViewCell
var todo = todos[indexPath.row]
cell.textLabel?.text = todo.objectForKey("description") as? String
return cell
}
UITableView の描画は UITableViewDelegate の対応するメソッドで行います。
サーバから取得した Todo データは todos プロパティに格納されています。 numberOfRowsInSection() は、todos に格納されているオブジェクト数をテーブルの行数として返します。
cellForRowAtIndexPath() で、具体的な TableView の cell を返却します。 todos の indexPath.row 番目の要素を取り出し、"description" キーに格納された文字列を cell のテキストとして 設定して返却します。
4.5.4. Todo の追加¶
画面右上の Add ボタンを押すと、Todo の追加処理に移ります。 この処理は Segue 経由で TodoEditViewController を起動することで行っています。
TodoEditViewController の Done ボタンを押すと TodoListViewController に戻りますが、 この際 todoText プロパティに設定されたテキストを保管します。
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
self.todoText = self.textView!.text;
}
TodoListViewController は、上記テキストを取り出し、addTodo() を呼び出します。
@IBAction func firstViewReturnActionForSegue(segue: UIStoryboardSegue) {
if (segue.identifier == "done") {
var vc = segue.sourceViewController as TodoEditViewController
var todo = vc.todoText
addTodo(todo)
}
}
addTodo() では、Todo の追加処理を行います。
func addTodo(description: String) {
// オブジェクト作成
var todo = NBObject(bucketName: BUCKET_NAME)
// オブジェクトに値を設定
todo.setObject(description, forKey: "description")
// オブジェクト保存
showIndicator()
todo.saveInBackgroundWithBlock({objects, count, error in
self.hideIndicator()
if (error == nil) {
self.reloadTodos(nil)
} else {
NSLog("save error : %@", error);
}
})
}
Todo データを NBObject クラスのインスタンスとして生成します。このとき、バケット名を指定します。
また、setObject() を呼び出して、description フィールドに Todo のテキストをセットします。
データの保存には saveInBackgroundWithBlock() メソッドを使用します。 このメソッドが呼び出されるとサーバにデータが送信され、処理が終了するとクロージャが呼び出されます。 ここでは reloadTodos() を呼び出して画面更新処理を行います。
4.5.5. Todo の削除¶
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true // 削除可能
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
var obj = todos[indexPath.row]
// オブジェクト削除
obj.deleteInBackgroundWithBlock({error in
self.hideIndicator()
if (error == nil) {
self.reloadTodos(nil)
} else {
NSLog("Delete failed: %@", error)
}
})
showIndicator()
}
Todo の削除処理は、tableView:commitEditingStyle:forRowAtIndexPath: で行います。 本処理は、Todo を左スワイプしたときに呼び出されます。
todos プロパティから、該当 NBObject インスタンスを取得し、 deleteInBackgroundWithBlock() を呼び出すとサーバに削除指示が送信されます。
削除が正常に完了するとクロージャが呼び出されますので、画面をリロードします。