MizuhoHackathon 実装メモ


MizuhoHackathonでVirtual Private Assistantを部分的にPepperで実現しようとしたときのメモです。

僕の担当分はチャットアプリでした。こんな感じの動作をします。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Mizuho Hackathonで作成したiOSアプリのデモ <a href="https://t.co/M9e0qVNoYC">https://t.co/M9e0qVNoYC</a> <a href="https://twitter.com/YouTube">@YouTube</a>さんから</p>&mdash; 龍一郎 (@K_Ryuichirou) <a href="https://twitter.com/K_Ryuichirou/status/734704364535701507">2016年5月23日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
主な機能は次の2つです。

1. チャット
2. iBeaconによる来店通知

それぞれどんな感じで実装したか、書く気があるうちに書いておきます。

I. チャット
================================================================================

基本方針は速度優先です。現状、チャットの実装で最速の手段はLINE Botを使い実装すらしないというのが最適解です。
実際そのような方針をとったところを2組程度お見かけしました。

今回はBotの返すデータをBluemix上のWatsonサービス群を使ってパーソナライズしたいということを見据え、自分で実装しました。
ですが、今振り返るとLINE Botで良かったような。要反省ですね。

I.I UserInterface
--------------------------------------------------------------------------------

OSSを使って実装しました。使ったのはJSQMessagesViewControllerです。

* [JSQMessagesViewController](http://www.jessesquires.com/JSQMessagesViewController/)

この辺を参考にして実装しました。というか、サンプルアプリを改変して実装しました。

* [JSQMessagesViewController/SwiftExample/SwiftExample at develop · jessesquires/JSQMessagesViewController · GitHub](https://github.com/jessesquires/JSQMessagesViewController/tree/develop/SwiftExample/SwiftExample)
* [JSQMessagesViewController/getting_started.md at develop · jessesquires/JSQMessagesViewController · GitHub](https://github.com/jessesquires/JSQMessagesViewController/blob/develop/Documentation/getting_started.md)
* [[iOS] JSQMessagesViewController でチャットアプリを実装する ｜ Developers.IO](http://dev.classmethod.jp/smartphone/iphone/jsq-messages-view-controller/)

この辺り見た感じだとFirebaseを組み合わせるとより高速化できたんじゃないかと思います。

* [FirebaseとJSQMessagesViewControllerを組み合わせてチャットアプリのサンプルを作ってみた - Qiita](http://qiita.com/mugicha/items/ef674209487fb182aaa6)



I.II. Network
--------------------------------------------------------------------------------

慣れた道具で手早くが理想ですが、せっかくなのでSwiftで書いてました。こちらもOSS利用が基本方針です。

### SwiftyJSON

サーバーから受信したJSONをパースするのにSwiftyJSONを利用しました。

* [GitHub - lingoer/SwiftyJSON: The better way to deal with JSON data in Swift](https://github.com/lingoer/SwiftyJSON)

* [Swiftを使ってJSONを解析する - Qiita](http://qiita.com/yosi-q/items/7ad1db0dca7b2dd4c065)

* [Swiftで面倒なJSONの取り扱いを10倍便利にするSwiftyJSON - Qiita](http://qiita.com/yukihamada/items/9b0067f905418105a2c6)

* [[Swift]POSTでAPIを叩く方法。（そしてJSONを取得する。） - Qiita](http://qiita.com/mochizukikotaro/items/e2da2d3186ec24e291a6)

* [SwiftでHTTPリクエストする - Qiita](http://qiita.com/sushichop/items/ac4ae99b905ce523c2fe)

* [[iOS 8/Xcode 6] SwiftではじめるiOS開発 #3 [API取得＆JSONパース] ｜ Developers.IO](http://dev.classmethod.jp/references/ios-8-xcode-6-swift-api-json/)

### NSURLSession

通信にはNSURLSessionを用いてAlamofireは使いませんでした。今思うと使っておけばよかったです。

* [HTTP Request in Swift 2.0 - Qiita](http://qiita.com/Shirade/items/80d2ed2114d7352a7551)

### ポーリング・非同期処理・同期処理(dispatch_async)

なお、データの更新にはdispatch_asyncとか使って並列処理を書き、ポーリングしてやってました。
この実装の最中、mainスレッド以外でUI部分の更新をしてはいけないのを忘れていて、バグを発生させたりもしてました。

* [SwiftでGCDを使ってみよう！ - Takahiro Octopress Blog](http://grandbig.github.io/blog/2016/01/18/semaphore/)

* [[Swift] while文とdo-while文の違い - Qiita](http://qiita.com/ohkawa/items/f16ea0bbb6277dbfdb51)

こうやって見てみると、WebSocketとか、Firebase SDKとか使いたくなります。

* [チャットなどリアルタイム更新が必要なスマフォアプリの構成について考えてみた - Qiita](http://qiita.com/mono0926/items/bb7fdd912bc338096f57)

* [SwiftでWebSocket! - Takahiro Octopress Blog](http://grandbig.github.io/blog/2015/03/11/socketio-in-swift/)



II. iBeacon
================================================================================

Pepperに近づいたという情報を取得するため、iBeaconを利用しました。

なお、用語(セントラルとかペリフェラルとか)は次をご参照ください。

* [iBeacon について - Qiita](http://qiita.com/HIkaruSato/items/79d758394e838022e08c)


II.I. セントラル(BLE信号の受け手側): CoreLocation
--------------------------------------------------------------------------------

定石通り、CoreLocationを使いました。とはいえ、全く苦労しなかったわけではないです。

* [CoreBluetooth で出来る事 - Qiita](http://qiita.com/rnamiki/items/ea912393c4fb58e7a9b9)

* [SwiftとiBeaconを使ってお母さんが自分の部屋に近づいて来た事を警告するアプリをつくる - Qiita](http://qiita.com/oggata/items/5de43d71692d1abcff7c)

* [iBeaconDemo/ViewController.swift at master · oggata/iBeaconDemo · GitHub](https://github.com/oggata/iBeaconDemo/blob/master/iBeaconDemo/ViewController.swift)

* [iBeacon(3) - リージョン監視とレンジング](http://enamelsystems.com/0011/)

* [iBeacon Receiver in Swift 2.0 - Qiita](http://qiita.com/Shirade/items/ca9dcf111f2a7548cacf)

II.II. ペリフェラル(BLE信号の発信側)
--------------------------------------------------------------------------------

モノを持っていなかったので実装しようとしてハマりました(後述)。結局、AppStoreからiBeacon ScannerをDLし、iPhoneやiPadをiiBeaconとして動作させて解決しました。

* [ASCII.jp：iPhone／iPadが2台あればOK、iBeaconを実体験する (2/2)｜Apple Geeks](http://ascii.jp/elem/000/000/964/964201/index-2.html)

III. ハマったところ
================================================================================

上記の通り色々やりましたが、何事も無く順調なわけでもなかったです。

III.I. CocoaPods利用不可
--------------------------------------------------------------------------------

開発しようとしたらOS X を El Capitanにアップデートしていたのでrootlessの影響をバッチリ受けてCocoaPods利用不可になってました。

頑張ってインストールするフォルダを変更して対処しました。

* [MacOSX El Capitanでcocoapodsインストールが出来ない時の対処法 - Qiita](http://qiita.com/AcaiBowl/items/4bb4708de03e6ee14a4a)

* [CocoaPods Guides - Getting Started](http://guides.cocoapods.org/using/getting-started.html#sudo-less-installation)

III.II. JSQMessagesViewControllerがSwiftじゃない
--------------------------------------------------------------------------------

せっかくなのでSwiftで開発しようとしたらJSQMessagesViewControllerがObjective-C。
普通にObjective-C bridging headerを作成して対処しました。

* [EZ-NET: Objective-C で定義したクラスを Swift で利用する : Swift プログラミング](http://program.station.ez-net.jp/special/handbook/swift/class/objc.asp)

* [SwiftとObjective-Cを共存させる - WonderPlanet DEVELOPER BLOG](http://developer.wonderpla.net/entry/blog/engineer/SwiftWithObjective-C/)

* [SwiftでObjCも利用したアプリ開発のときにハマったこと - Qiita](http://qiita.com/susieyy/items/fea63b5261942a127c19)


でもよく見るとJSQMessagesViewControllerがSwift対応済みでした。結局、SwiftExampleフォルダ以下のサンプルプロジェクトを利用しました。

* [JSQMessagesViewController/SwiftExample/SwiftExample at develop · jessesquires/JSQMessagesViewController · GitHub](https://github.com/jessesquires/JSQMessagesViewController/tree/develop/SwiftExample/SwiftExample)



III.III. 画面遷移がSegueだけどSegueよく知らない
--------------------------------------------------------------------------------

調べればなんとかなる。

* [Swiftでセグエを利用した画面遷移 - Qiita](http://qiita.com/tajihiro/items/45c7adf2ef15df79bbf1)

* [Storyboardのsegueでパラメタ受け渡したった - Qiita](http://qiita.com/toguri/items/6eba4e57dffa993b4933)


III.IV. ViewControllerのプロパティ
--------------------------------------------------------------------------------

プロパティにvarを使ったらinitを実装しなければいけないのだけれど結構面倒でした…。なおかつ、ViewControllerのインスタンスを作成した時点では確定しないものについてはOptional を使わなければいけないから結構気を使いました。(nilでアプリが落ちた箇所については後述)

* [ViewControllerのプロパティをOptional型で宣言する | Cyber Passion for iOS](http://blogios.stack3.net/archives/2650)

* [Swiftに関するメモ その5 - 初期化処理・終了処理 - Qiita](http://qiita.com/takkyun/items/afde067c08bc046ffe53)

* [クラス | Swift言語を学ぶ](http://tea-leaves.jp/swift/content/%E3%82%AF%E3%83%A9%E3%82%B9)

* [プロパティ | Swift言語を学ぶ](http://tea-leaves.jp/swift/content/%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3)

III.V. Settings.bundleでの設定ができない
--------------------------------------------------------------------------------

アプリへの設定用画面を作るのが面倒だったので、Settings.bundleを用いた設定アプリの利用をやろうとしたときのこと。
アプリインストール直後、何らかの値の保存前ににSettings.bundleにアクセスするとnilへのアクセスになって、強制アンラップすると落ちます。

結局、アプリの設定要画面を作成してSettings.bundleは使いませんでした。

* [iPhone アプリ研究会 iPhoneアプリを「設定画面」にて設定するための手順](http://appteam.blog114.fc2.com/blog-entry-199.html)

* [[Swift] 地味によく使う設定値の保存、取得をしてみる（NSUserDefaultsの利用） - Qiita](http://qiita.com/m-tsuchiya/items/5e919813be19fb4b53bf)

III.VI. UIButtonの枠線設定がInterfaceBuilderからできない
--------------------------------------------------------------------------------

「いつもやってるのになんで出来ないんだろ」と思っていたら、クラスを書くのを忘れていました。これは本当に便利なのでXcode側で実装しておいてくれないかな。

* [UIButtonの角丸とか枠線とかをInterfaceBuilderで設定＆確認できるようにする。 - Qiita](http://qiita.com/Kta-M/items/ae22fd0c78cb15faee0b)


III.VII. 数値と文字列の相互変換
--------------------------------------------------------------------------------

Swiftでの数値と文字列の相互変換はSwiftのバージョンによって書き方が違うのに驚きました。こんなところまでまだ変わっていくんですね。

* [[iOS8] Swiftで文字列と数値の型変換する方法 - Qiita](http://qiita.com/hiroo0529/items/27ec2c24327a692aa0dd)

* [[iPhone] Int, String, Double 変換 (Swift)](https://akira-watson.com/iphone/swift/int-string-double.html)

* [Swiftで文字列<->日付の相互変換をする | hacknote](http://hacknote.jp/archives/10562/)


III.VIII. 忘れてたATS
--------------------------------------------------------------------------------

アプレッソ様のDataspiderを利用させて頂いたのだけど、まずつながらなかった。サーバー側にHTTPリクエストが届いていない状態だったので悩んだのだけど、よく考えなくてもATSでした。最近のiOSではHTTPSがこういう形で強要されてるの忘れてました。

* [iOS9 ATS問題 - Qiita](http://qiita.com/yanayanalte/items/e6d83c12af77fa238a58)

* [DataSpider Servista | アプレッソ](https://www.appresso.com/servista/)

III.IX. MacをiBeacon化できない
--------------------------------------------------------------------------------

iBeacon持っていないのにiBeaconの実装しなければいけないけどmacをiBeacon化すれば行けるだろ、そう思っていた時期がありました。

* [たった6行!最も簡単にiBeaconの電波を「発信」する方法 - Qiita](http://qiita.com/kpkpkp/items/a0dd3cfcd1eef8dbd492)

* [Mac OSX Yosemite（10.10.2）をBeacon化する方法 - Qiita](http://qiita.com/yuyaohshimo/items/d0faeed96f6a046b4b28)

でも動かない。理由はNode.jsのバージョンが適していなかったためのようです。

* [Node.js 学習帳-失敗事項　〜 iBeaconを使う何かを作ってみる〜 - Qiita](http://qiita.com/tagosaku324/items/1e3597d701720d89934e)

面倒だったので諦めてiOSアプリiBeacon Scannerを使いました。

III.IX. iPhoneをiBeacon化できない
--------------------------------------------------------------------------------

でも動かない。1時間位ハマりました。色々試しましたが、最終的に分かったことは「iPhoneのBlueToothがOffになっていたのでiBeaconとして動作しない」ということでした…。

iBeacon Scannerを使うときにはBlueToothをOnにしましょう。

III.X. アプリのアイコン画像を用意するのが面倒
--------------------------------------------------------------------------------

アプリアイコンは一つの画像じゃなくていくつもサイズを用意して一つ一つ手作業登録という作業をなんとかしたいのですが、今回そういう方法は見つからなかったのでひとつひとつ手作業で登録してます。

せめてアイコンの画像くらいは自動生成したかったので、1024x1024の画像をWebサービスでリサイズして利用しました。

* [iOSアプリの画像の作り方[Xcode6] - Qiita](http://qiita.com/Yuta/items/ad02e5e93694c8add089)

* [iOS・Android アプリのアイコンの一括リサイズをやってます](http://araishi.com/icon-resize/)

III.XI. アプリ名の変更の仕方を忘れてた
--------------------------------------------------------------------------------

プロジェクトの設定でどこに何を設定するとどういう効果があるのかを理解できる日はいつ来るのでしょうか。アプリ開発指南書はたくさんありますが、プロジェクトの設定項目について解説しているものはほとんど見かけないような気がします。

今回もホーム画面で表示されるアプリ名を変更したかっただけだったのですが、それがどこで設定されているのか分からず、次の記事にあるすべての箇所で変更を行いました。

* [[iOS] アプリ名を変更する - Qiita](http://qiita.com/hiroo0529/items/24b027b9708d14200b56)

III.XII. JSQMessagesViewControllerのアイコン画像が設定できない(未解決)
--------------------------------------------------------------------------------

本当に自分でも呆れてるのですが、UIImageがうまく使えませんでした…。近いうちにリベンジします。

* [SwiftでUIImageのimageNamed:でファイルが存在しなかったときに起こる謎 - Qiita](http://qiita.com/mo_to_44/items/c3a769f9fc2fb1367513)

* [iPhoneアプリ作成で画像を扱う時の注意点 - 今日も明日も♪青空日記](http://kyo-asu-aozora.seesaa.net/article/257890808.html)

* [ios - UIImage imageNamed returns nil - Stack Overflow](http://stackoverflow.com/questions/10998544/uiimage-imagenamed-returns-nil)

III.XIII. Swiftで書いたソースにBreakpointを設定したときのXcodeの動作がObjective-Cと違う(未解決)
--------------------------------------------------------------------------------

Objective-Cだと「ここ！この行だよ今実行しているのは！あとそれぞれのオブジェクトの中身今こんな感じね！」って感じに表示してくれるのですが、Swiftだと「Breakpoint来たから止めたで。行数はこの画面のどこかに探したから自分で探せや」って感じでした。

この辺りは慣れなんですかね…？

IV. その他
================================================================================

Swiftの基本文法は調べながら書いてました。こういうのは検索する必要なく調べられるようになっておきたいです。

* [Swift さくっと確認したい基礎文法 [いろんなループ処理] - Qiita](http://qiita.com/yuinchirn/items/4c1295c3582adef8c98f)

* [[Swift] 配列と辞書 - Qiita](http://qiita.com/Linon/items/084f46b932d5e6a6a5ae)

最後に
================================================================================

Pepperを使ったハッカソンに参加するのはコレで3度目なのですが、1度目に作ったアプリは「Pepperの操作をiPhoneから行う」というものでした。これはこれで悪くないかもしれないのですが、個人的には方向性を誤ったとそれ以降反省しているシロモノです。

それ以降、2回目、3回目とPepperに指示を出さないアプリに取り組んでみたのですが、今回は「Pepperとコミュニケーションする」というコンセプトを部分的に実現できた点は進歩かなと。

実際、Pepperを何かを行うためのツールとして捉えると、大概の場合他にもっと良い手段があります。技術的に捉えると、Pepperは胸にブラウザが搭載されている人型のLinuxマシンで、カメラやスピーカー・近接センサーがついています。LinuxマシンというよりはAndroidの方が近いかもしれないです。が、センサーは高級Android端末ほどではありませんし処理能力もあんまり高くないです。何らかの処理を行うためのスペックは低いといって差し支えないと思います。

一旦角度を変えて過去に視点を向けます。今までに流行したコンシューマー用ロボットはあまりなく、家庭に入りこんだ例はほとんどありません。例外は2つあり、Aiboとルンバです。特にAiboは「ロボットに人間が奉仕する」形で使われているため、通常のコンピューターやロボットの用途とはかけ離れています。

個人的に、Pepperがコミュニケーション用のロボットだというのは、Pepperの持つ何らかの機能を指すのではなく、人間がPepperから影響をうけて何かしたくなる人間側の錯覚を指すのだと理解しています。Pepperの手助けをしたくなるような、Pepperに奉仕したくなるような、我々の持つ感覚を呼び起こすのがPepperというロボットの特徴ではないでしょうか。

というわけでそういったアプリを作成してみたいのですが、過去に余り例がないのですよね。シーマン・たまごっち・デジモンあたりの育成アプリが参考になるでしょうか。次はもっと役に立たないアプリを作成しようと思います。