mobile backendはRomoアプリ実装でも楽に活用！

mobilebackend運用しています。こちらの記事の元は[こちら] (https://github.com/NIFTYCloud-mbaas/UserCommunity/issues/192). 初めてロボットを触って、mobile backendを使ってデモを作りましたが、作成した手順などシェアさせてください。

* 本記事は、ニフティクラウドmobile backend各種展示会ブースにて展示している【Romo】デモの実装TIPSになります！
* デモに使用しているサービス群
 - [Nifty cloud mobile backend](http://mb.cloud.nifty.com/)
 - [Nifty cloud](http://cloud.nifty.com/)
 - [Nifty cloud MQTT](http://cloud.nifty.com/service/mqtt.htm)
 - [Nifty cloud C4SA](http://c4sa.nifty.com/)

# What is Romo? Romo（ロモ）って何？

[Romo](http://www.romotive.jp/)
公式サイトより：
     Romo（ロモ）はiPhoneやiPod touchを使って楽しくプログラミングを学べる知育ロボットです。

つまり、iPhoneやiPodをつければ、様々なことができるロボットの一種になります！

# How to develop for Romo? どうやってRomoアプリ開発を行うの？

基本的にはiOSアプリ開発を行う形になります。
Romoに取り付けるiPhone/iPod上で動作するiOSアプリを作ることで、ロモの制御が可能です！

ロモ社からは、ロモ専用のSDKが下記の通り2つ提供されています。

* RM Core Framework（本体の制御）

LEDの制御、iPhoneの角度の制御、左右のキャタピラの回転

* RM CharacterFremework（Romoアプリ内のキャラクターの制御）

視線、発話、目の開閉、感情の表現

これらのSDKを使えば、Romoをコントロールするのは簡単そうですね。

# What I did with Romo?　Romo（ロモ）と何をしたのか？

Romoの機能を活用すれば、色んなことが出来そうです。
たとえば、カーレースのようなゲームを作る記事なども公開されていました。

今回は、ゲームのようなものではなく、何か生活に役に立つものをRomoと行えないか考えてみました。

Romoは自由に動き回ることができ、iPhoneのカメラも利用できます。
それらを組み合わせれば、ボディーガードとまではいかなくとも、
家の状況や子供・ペットの状況を監視することはできそうですね！

今回は、Romoを遠隔操作で自由に走らせ、ビデオ通信で状況を把握したり、
写真を撮って登録した端末へプッシュ通知で送るようなRomoアプリを作っていきたいと思います。

また、今回の実装はニフティクラウドmobile backendだけではなく、
ニフティクラウドの様々なサービスを組み合わせて行っていきます。

# How to? どうやって行ったか？

構成要素は主に下記の3つです。
 - コントローラー: ビデオを受信し、Romoへ写真を撮る命令を送る
 - Romoクライアント: ビデオを送信し、Romoの制御を受け、写真を撮る
 - プッシュ通知受信クライアント：プッシュ通知の受信

以下は、展示会ブース等でも使用した今回のRomoアプリの説明図です。
![Romo構成](https://goo.gl/qjb3g6)

* Romoの制御：[ニフティクラウドMQTT](http://cloud.nifty.com/service/mqtt.htm)により実装。

* Romoのビデオ通信：[ニフティクラウド](http://cloud.nifty.com/)でWEB-RTCを構築。

* Romoから画像写真をアップロード／Push通知を送信: [ニフティクラウドmobile backend](http://mb.cloud.nifty.com/) <- 今回はここをメインに説明します！

# Romoからファイルストアに画像をアップロードする

```
       //保存するファイル名の生成
       [self.localView setHidden:false];
       NSDate *currentTime = [NSDate date];
       NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
       [dateFormatter setDateFormat:@"yyyyMMddHHmmss"];
       NSString *resultString = [dateFormatter stringFromDate: currentTime];
       NSString *fileName = [resultString stringByAppendingString:@".jpg"];

       //mbaasの初期化
       [NCMB setApplicationKey:NCMB_ApplicationKey clientKey:NCMB_ClientKey];

       //データストアへファイル名の保存
       NCMBObject *imageData = [NCMBObject objectWithClassName:@"image"];
       [imageData setObject:fileName forKey:@"imagetitle"];
       [imageData saveInBackgroundWithBlock:nil];

       // ファイルストアへ画像のアップロード
       GLKView *tempview = self.localView.subviews[0];
       UIImage *image = [tempview snapshot];
       [self.localView setHidden:true];
       NSData *jpgData = [[NSData alloc] initWithData:UIImagePNGRepresentation(image)] ;
       NCMBFile *file = [NCMBFile fileWithName:fileName data:jpgData];
       [file saveInBackgroundWithBlock:nil];
```

少しソースコードの説明をします。

まず、ファイル名を現在時刻の文字列より生成します。
その後、データストアへファイル名を、ファイルストアへ画像を保存します。データストアと連携を行うのは、ファイル名で画像を検索できるようにするためです。

画像は、以下のドキュメントを参考に、NSDataに変換したものを保存します。
http://mb.cloud.nifty.com/doc/sdkguide/ios/filestore.html

# プッシュ通知の実装

写真のアップロードが完了したら、指定した端末へプッシュ通知を配信します。
端末がプッシュ通知を受信したら、アップロードした画像がポップアップで出てくるような実装とします。
※写真については、公開ファイルか、もしくは別途URLを準備する必要があります。

以下のプッシュ通知登録ドキュメントをご参考ください。
http://mb.cloud.nifty.com/doc/sdkguide/ios/push.html

```
       //Sendpush
       NSString *richUrlStr = [@"http://cy8srgt-ac3-app000.c4sa.net/romo-js/#/push/" stringByAppendingString:fileName];
       NCMBPush *push = [NCMBPush push];
       NSDictionary *data = @{};
       [push setData:data];
       [push setMessage:@"it`s a pic from romo"];
       [push setImmediateDeliveryFlag:true];
       [push setPushToAndroid:true];
       NCMBQuery *query = [NCMBInstallation query];
       [query whereKey:@"iot" equalTo:self.pushid]; //installation class setting: string "1" 
       [push setRichUrl:richUrlStr];
       [push setSearchCondition:query];
       [push sendPushInBackgroundWithBlock:^(NSError *error) {
           NSLog(@"[Error] %@", error);
       }];
```

setDataおよびsetMessageにてプッシュ通知の中身を設定します。
また、setImmediateDeliveryFlagをtrueにして、即時配信されるように設定しました。
対象端末はAndroidです。

今回、プッシュ通知は設定時に入力された「pushid」と同じ番号が割り振られている端末へ配信する形をとります。
まず、NCMBInstallationのqueryを作成し、「iotフィールドにpushidと同じ番号が入っている」という条件にしてから、setSearchConditionにqueryを指定します。

最後に、sendInBackgroundWithBlockで非同期的にプッシュ通知を登録します。

# プッシュ通知受信処理

AndroidでもiOSでも受信することが可能です。
以下のサンプルをご参考ください。

* [Android Push](http://mb.cloud.nifty.com/doc/sdkguide/android/push.html)
* [iOS Push](http://mb.cloud.nifty.com/doc/sdkguide/ios/push.html)

# ソースコード公開中

以下のGithubにアップしていますので、ぜひご参考ください。
※サーバー設定、APIキー設定などの修正が必要です。

* [Github romo controller](https://github.com/kuroei/NifRomoController)
* [Github romo client](https://github.com/kuroei/NifRomoClient)

# Reference - 参照

* [Romo](http://www.romotive.jp/)