3. チュートリアル1 : TODOアプリの実装

ここではチュートリアル1の実装について解説します。

3.1. NEC BaaS SDK Framework の追加

NEC BaaS iOS SDK を利用するためには、アプリケーションに Nebula SDK Framework を追加する必要があります。

注釈

チュートリアルプロジェクトにはすでに追加済みのため、以下の手順を行う必要はありません。

BaaS SDK Framework を追加するには、以下の手順を行います。

SDK を追加するプロジェクトを Xcode で開き、nebulaIosSdk.framework フォルダを Xcode プロジェクトにドラッグして追加します。 (事前に Frameworks グループを作成しておくことを推奨します)

_images/addFramework1.png

この際、以下のように 'Copy items if needed' に必ずチェックを入れてください。 (チェックを入れないと、ファイルがコピーされません)

_images/addFramework2.png

Xcode の Targets →アプリ名 →Build Phases タブを開き、 "Link Binary With Libraries" を展開します。

nebulaIosSdk.framework が追加されていることを確認してください。 追加されていない場合は、下部にある '+' ボタンを押して追加してください。

_images/addFramework3.png

3.2. ヘッダファイルの import

iOS SDK を使用するソースファイルは、適宜 nebulaIosSdk/Nebula.h ファイルを import する必要があります。

#import "nebulaIosSdk/Nebula.h"

3.3. AppDelegate クラス

AppDelegate クラスの application:didFinishLaunchingWithOptions: メソッド内で、 iOS SDK の初期化処理を行います。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Nebula 初期化処理
    [NBCore setUpWithAppId:APP_ID appKey:APP_KEY tenantId:TENANT_ID];
    [NBCore setEndPointUri:ENDPOINT_URI];

    return YES;
}

SDK の初期化には NBCore クラスを使用します。 setupWithAppId:appKey:tenantId: を使用して以下のパラメータを設定します。

  • テナントID
  • アプリケーションID
  • アプリケーションキー

また、setEndPointUri: を使用して、エンドポイントURIを設定します。

3.4. TodoListViewController クラス

アプリケーション本体は TodoListViewController クラスに実装します。 本クラスは UITableViewController を継承しており、Todo を Table View で表示します。

3.4.1. 初期化 (viewDidLoad)

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"TodoCell"];

    self.todos = @[]; // initial
    [self reloadTodos:nil];
}

初期化は viewDidLoad で行います。

ここでは reloadTodos: を呼び出し、Todo 一覧の取得を開始しています。

3.4.2. Todo 一覧の取得

// Todo 一覧を取得する
- (IBAction)reloadTodos:(id)sender {
    // バケット取得
    NBObjectBucket *bucket = [[NBObjectBucket alloc] initWithBucketName:BUCKET_NAME];

    // クエリ生成
    NBQuery *query = [NBQuery new];
    [query setSortOrderWithKey:@"updatedAt" isAscend:YES];

    // クエリ実行
    [bucket queryInBackgroundWithQuery:query block:^(NSArray *objects, NSUInteger count, NSError *error) {
        if (!error) {
            self.todos = objects;
            [self.tableView reloadData];
        } else {
            NSLog(@"query error: %@", error);
        }
    }];
}

reloadTodos: で、サーバから Todo データの一覧を取得します。

最初にオブジェクトバケットのインスタンスを取得します。オブジェクトバケットは NBObjectBucket クラスの インスタンスとして作成し、initWithBucketName: でバケット名をセットします。

Todo データは、NBObjectBucket に対して queryInBackgroundWithQuery:block: を呼び出すことで取得できます。 クエリ(取得条件)は NBQuery クラスのインスタンスとして作成します。 ここでは更新日時(updatedAt)フィールド昇順で、全件取得するというクエリを作成しています。

処理が完了すると、block: 引数に指定したブロックが呼び出されます。 正常時は objects にオブジェクトの一覧が、error に nil が格納されます。 ここでは todos プロパティに objects を保存し、tableView の reloadData を呼び出して画面描画を行います。

3.4.3. 画面描画

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.todos count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"TodoCell"];

    NBObject *todo = (self.todos)[indexPath.row];

    cell.textLabel.text = [todo objectForKey:@"description"];
    return cell;
}

UITableView の描画は UITableViewDelegate の対応するメソッドで行います。

サーバから取得した Todo データは todos プロパティに格納されています。 tableView:numberOfRowsInSection: は、todos に格納されているオブジェクト数をテーブルの行数として返します。

tableView:cellForRowAtIndexPath: で、具体的な TableView の cell を返却します。 todos の indexPath.row 番目の要素を取り出し、"description" キーに格納された文字列を cell のテキストとして 設定して返却します。

3.4.4. Todo の追加

画面右上の Add ボタンを押すと、Todo の追加処理に移ります。 この処理は Segue 経由で TodoEditViewController を起動することで行っています。

TodoEditViewController の Done ボタンを押すと TodoListViewController に戻りますが、 この際 todoText プロパティに設定されたテキストを保管します。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    self.todoText = textView.text;
}

TodoListViewController は、上記テキストを取り出し、addTodo: を呼び出します。

- (IBAction)firstViewReturnActionForSegue:(UIStoryboardSegue *)segue
{
    if ([segue.identifier isEqualToString:@"done"]) {
        TodoEditViewController *vc = [segue sourceViewController];
        NSString *todo = vc.todoText;
        [self addTodo:todo];
    }
}

addTodo: では、Todo の追加処理を行います。

- (void)addTodo:(NSString *)description {
    // オブジェクト作成
    NBObject *todo = [NBObject objectWithBucketName:BUCKET_NAME];

   // オブジェクトに値を設定
    [todo setObject:description forKey:@"description"];

    // オブジェクト保存
    [todo saveInBackgroundWithBlock:^(NSArray *objects, NSUInteger count, NSError *error) {
        if (!error) {
            [self reloadTodos:nil];
        } else {
            NSLog(@"save error : %@", error);
        }
    }];
}

Todo データを NBObject クラスのインスタンスとして生成します。このとき、バケット名を指定します。

また、setObject:forKey: を呼び出して、description フィールドに Todo のテキストをセットします。

データの保存には saveInBackgroundWithBlock: メソッドを使用します。 このメソッドが呼び出されるとサーバにデータが送信され、処理が終了するとブロックが呼び出されます。 ここでは reloadTodos: を呼び出して画面更新処理を行います。

3.4.5. Todo の削除

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES; // 削除可能
}

// 削除処理
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NBObject *obj = (self.todos)[indexPath.row];

    // オブジェクト削除
    [obj deleteInBackgroundWithBlock:^(NSError *error) {
        if (!error) {
            [self reloadTodos:nil];
        } else {
            NSLog(@"Delete failed: %@", error);
        }
    }];
}

Todo の削除処理は、tableView:commitEditingStyle:forRowAtIndexPath: で行います。 本処理は、Todo を左スワイプしたときに呼び出されます。

todos プロパティから、該当 NBObject インスタンスを取得し、 deleteInBackgroundWithBlock: を呼び出すとサーバに削除指示が送信されます。

削除が正常に完了するとブロックが呼び出されますので、画面をリロードします。