はじめに
日本では2013年4月に発売され、売り切れ店続出、その後も品薄状態が続いたほどの人気を博した「Jawbone UP」ですが、つい先日、その後継となる「UP24」が発売されました。
UP24
新モデルの特長は、なんといっても「Bluetooth Smart」( ※1 )を採用したこと。これにより、ワイヤレスでのiOS/Androidデバイスの同期が可能 となりました。
……と書くとケーブルで繋ぐ煩わしさが少し解消されただけ、という印象になってしまいますが、iPhoneやiPadのようなモバイルデバイスと連携するガジェットにおいては、「 ワイヤレスで」「 リアルタイムに」データ連携できるというのは、かなり重要な進歩ではないでしょうか。
本記事では、この「UP24」および前機種「UP」と連携するiOSアプリの実装方法 を紹介します。
UP24のデバイス仕様
UP24公式サイトのTECH SPECS ページによると、
重量はサイズごとに違っていて 19g~23g
バッテリーの持ちは7日間
搭載されているセンサやインターフェースモジュール
Bluetooth 4.0 BLE
3軸加速度センサ
カラーLED
バイブレーションモータ
とあります。
M7搭載iOSデバイスに対する優位性
BLEは通信用、LEDやバイブはユーザインターフェースとしての役割なので、上記のスペックだけみると、実質的には「リストバンド型加速度センサ」です。
3軸加速度センサはiOSデバイスにも昔からついているし、iPhone 5s以降の上位機種ではM7コプロセッサで省電力に、かつジャイロやコンパス等と統合的に、かつバックグラウンドでも処理してくれるようにもなったので、たとえば、5sユーザにとってはあまりUP/UP24を別途利用するメリットが薄いようにも思えるかもしれません。
しかし、当然のことながらiPhone 5sは腕には巻けないので、寝ている間ずっと身につけておくのはなかなか難しくなります。
また、加速度センサの生データを処理して睡眠状態を把握するのは、その分野の専門知識やデータ解析ノウハウが必要になってきます。
ですから、モーションアクティビティを利用可能なiOSデバイスユーザにとっても、UP24を利用する価値は大いにあるのではないでしょうか。
購入方法
Apple Store(JAPAN) やAmazon で国内正規品 が販売されています。
UP Platform iOS SDKを用いたアプリの実装方法
公式アプリを使用したUP24の「一般的な使用方法」は本記事では省略し、以下ではJAWBONEからオフィシャルにリリースされている、「UP Platform iOS SDK」を使用して自作iOSアプリとUP24を連携させる 方法を紹介します。
Client IDとApp Secretの取得
①サインイン
JAWBONEのデベロッパーサイトにサインイン(もしアカウントがまだなければサインアップ)します。
②Organizationを作成する
"Create an Account"メニューをクリックし、フォームに必要項目を入力(ロゴ画像のアップロードはオプション)して送信します。
③Appを作成する
Organizationが生成されると、"Create an Account"があった場所が、"Manage Account"というメニューになり、そこから"Create App"できるようになります。
フォームの必要項目を入力し、送信すると、Client IDとApp Secretが生成されるので、メモしておきます。
SDKをプロジェクトに導入する
GitHubのREADMEでは、UPPlatformSDK.framework(ビルド済みバイナリとヘッダファイルで構成される)をプロジェクトに追加するかたちでの導入方法が書かれているのですが、こういうプロダクトに付属のSDKとしては珍しく、ソース一式もリポジトリに 含まれています。
デベロッパー側としては、ソースコードがあった方が何かと都合がいいので、本記事では.frameworkではなく、ソースコードを追加するかたちでの導入方法を紹介します。
①SDKを取得
GitHubリポジトリからSDKをcloneします。
$ git clone git@github.com:Jawbone/UPPlatformSDK.git
②プロジェクトに追加
リポジトリ内にある、"UPPlatformSDK"フォルダごとプロジェクトに追加します(UPPlatformSDK-Info.plistやUPPlatformSDK-Prefix.pchは不要なので削除してOK) 。
③ヘッダをインポート
SDKを使用するビューコントローラで、ヘッダをインポートします。
#import "UPPlatformSDK.h"
④ログイン処理
前述した手順で取得したClient IDとApp Secretを定義しておき、
NSString *const kAPIClientID = @"xxxx";
NSString *const kAPIAppSecret = @"xxxxxxxxxxxxxxxxxxx";
ログインボタン等をタップした際のアクション等の処理の中で、startSessionWithClientID:clientSecret:authScope:completion:メソッドを実行します。
[[UPPlatform sharedPlatform] startSessionWithClientID:kAPIClientID
clientSecret:kAPIAppSecret
authScope:UPPlatformAuthScopeAll
completion:^(UPSession *session, NSError *error) {
NSLog(@"error:%@, session:%@", error, session);
}];
これにより、次のようにログイン用のUIが表示されるようになります。
ログイン画面
startSessionWithClientID:~メソッドの第3引数"authScope"は、そのアプリで「どの範囲までユーザから許可をもらうか」を指定します(FacebookでいうPermissionのようなもの) 。
たとえば上記では、UPPlatformAuthScopeAllを指定しているので、サインイン後の画面では、「 読み書き可能なすべてのデータに対してのアクセス要求」が行われます。
アクセス要求画面
運動データを取得する
UP Platformから運動に関する情報を取得するためのメソッドは2種類用意されています。
1つは、開始日時と終了日時で取得範囲を指定 するgetMovesFromStartDate:~メソッドです。
NSDate *endDate = [NSDate date];
timeIntervalSince1970] - (24 * 60 * 60 * 14)];
NSDate *startDate = [NSDate dateWithTimeIntervalSince1970:0.];
[UPMoveAPI getMovesFromStartDate:startDate
toEndDate:endDate
completion:^(NSArray *results, UPURLResponse *response, NSError *error) {
}];
もう1つは、取得するUPMoveオブジェクトの上限数を指定 するgetMovesWithLimit:completion:メソッドです。
[UPMoveAPI getMovesWithLimit:1 completion:^(NSArray *results, UPURLResponse *response, NSError *error) {
}];
どちらもcompletionブロックのresults引数には、UPMoveオブジェクトの配列が入ってきます。
UPMoveはユーザの1日の活動に関する情報を格納 するクラスなので、getMovesWithLimit:completion:は「取得する日数を指定する」メソッドと言えます。
グラフ表示
ためしにUPMoveオブジェクトの1つをログ出力してみると、
> UPMove: { xid: xxxxxxxxx, title: 16,054歩, date: 2014-04-11 15:00:00 +0000, activeTime: 8654, inactiveTime: 13868, restingCalories: 1506.88983472, activeCalories: 750.906708623, totalCalories: 2257.797, distance: 11.925, steps: 16054, longestIdle: 6360, longestActive: 3442, imageURL: https://jawbone.com/nudge/image/e/xxxxxx/xxxxxx/xxxxx.png } }
このように、さまざまな情報が取れていることがわかりますが、いきなりこれだけの数字が並んでも何がなんだかわかりません。
そこで、次のように、UPMoveオブジェクトをgetMoveGraphImage:completion:メソッドに渡してみます。
[UPMoveAPI getMoveGraphImage:move
completion:^(UIImage *image) {
UIViewController *viewCtr = [[UIViewController alloc] init];
[self.navigationController pushViewController:viewCtr animated:YES];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[viewCtr.view addSubview:imageView];
}];
すると、次のように、その日の活動状況を示すグラフ を表示できます。
その日の活動状況を示すグラフ
これは、Jawbone社が公開しているiOS向けグラフ描画ライブラリJBChartView を使用……しているものと思いきや、グラフ画像を生成しているのはUP Platformのサーバ側です。
getMoveGraphImage:~は、UPMoveのプロパティから画像URLを取得し、そのURLにある画像データからUIImageオブジェクトを生成するだけのメソッドです。
詳細なデータを取得する
より細かい運動データを取得 し、自分でグラフ描画等を行いたい場合にはgetMoveTicks:completion:メソッドにUPMoveオブジェクトを渡すと、UPMoveTickオブジェクトの配列を得られます。
[UPMoveAPI getMoveTicks:move
completion:^(NSArray *results, UPURLResponse *response, NSError *error) {
}];
最小で1分間隔のデータが得られます。
"UPMoveTick: { activeTime: 9, calories: 0.79699999094, distance: 15, speed: 1.66700005531, steps: 19, timestamp: 2014-04-12 04:32:00 +0000 }",
"UPMoveTick: { activeTime: 10, calories: 0.617999970913, distance: 12, speed: 1.20000004768, steps: 17, timestamp: 2014-04-12 04:33:00 +0000 }",
"UPMoveTick: { activeTime: 9, calories: 0.79699999094, distance: 15, speed: 1.66700005531, steps: 19, timestamp: 2014-04-12 04:55:00 +0000 }",
"UPMoveTick: { activeTime: 60, calories: 5.44000005722, distance: 101, speed: 1.68299996853, steps: 132, timestamp: 2014-04-12 04:58:00 +0000 }",
"UPMoveTick: { activeTime: 60, calories: 0, distance: 93, speed: 1.54999995232, steps: 121, timestamp: 2014-04-12 04:59:00 +0000 }",
"UPMoveTick: { activeTime: 60, calories: 4.5689997673, distance: 94, speed: 1.56700003147, steps: 122, timestamp: 2014-04-12 05:00:00 +0000 }",
"UPMoveTick: { activeTime: 60, calories: 4.44299983978, distance: 91, speed: 1.51699995995, steps: 119, timestamp: 2014-04-12 05:01:00 +0000 }",
(以下略)
睡眠データを取得する
睡眠データも、API構成は運動データとほぼ同様 です。
getSleepsFromStartDate:toEndDate:completion:メソッドおよびgetSleepsWithLimit:completion:メソッドでUPSleepオブジェクトの配列を取得し、グラフ画像を取得するにはgetSleepGraphImage:completion:メソッドを、より細かいデータを得るにはgetSleepTicks:completion:メソッドを使用します。
その他のAPI
UPおよびUP24の加速度センサから得られる運動データ、および睡眠データの取得にフォーカスしてSDKの使い方を紹介しましたが、UP Platformは、上記以外にも、ユーザ情報やワークアウト、食事、ムード等々、多様な情報をGET/POSTできるAPI を備えています。
詳しくは、オフィシャルのAPIリファレンス と、リポジトリに付属のAPIExplorerサンプルをご参照ください。
BLE経由でのアクセスについて
上記で紹介した機能は、いずれもUP PlatformというWebサービスのAPIをSDKがラップしているだけで、BLEの機能は用いていません。
UP24を利用するからにはCore Bluetoothを利用してBLE経由で直接データを取得 したい、と思うかもしれません。
が、残念ながら、SDKのリポジトリのとあるissue で、「サードパーティ製アプリに対して、BLE経由でのアクセスは公式にはサポートしていない」 と中の人によってハッキリ回答されています。
将来的には検討している、とも書いてありますが、明確にロードマップにあるわけではなさそうです。
勝手にBLEパケットを取得して利用するのはOK?
UP24がブロードキャストしているBLEパケットの構造は単純なので、加速度センサの値もしくはそれに準ずるものが入ってそうなキャラクタリスティックを特定することは簡単です。その値がどのようなものか解析して特定することも可能そうです。
このようにしてBLEパケットを勝手に解析して取得したデータを使ってアプリをリリースすることは規約に反するか?という質問については、「 サポート窓口に問い合わせてください」と前述のissue内では回答されていました。
正直な感想
本記事冒頭で、「 iPhoneやiPadのようなモバイルデバイスと連携するガジェットにおいては、「 ワイヤレスで」「 リアルタイムに」データ連携できるというのは、かなり重要な進歩」と書きました。
これに対し、上述した通りSDKではBLE経由でのアクセスができない というのは、「 iOSアプリ開発と連携させて使えるデバイス」としては魅力半減です。せっかく独自アプリに組み込んで使えるSDKがあるのに、せっかくデバイスはBLEを搭載したのに、独自アプリからは「UPの公式アプリ」で取り込んだデータしか使えないわけですから……。
たとえばもしSDKで、BLE経由でリアルタイムに UP24 の情報を取れるとしたら、
「もうすぐ10000歩」をトリガとしてプッシュ通知を発行
睡眠状態を見てhue を自動で明るくする
といったことが可能になるわけで、これはアプリ開発者にとって夢がある!と期待して使ってみたのですが、残念です。
ただ、Jawbone社としては、BLE経由でサードパーティ製アプリにデータを使わせることで、自分たちのアプリや UP Platformが使われなくなってしまうと、ガジェット単体でしか収益を上げられず、今後のビジネス展開の可能性も狭まってしまうので、そこをわざわざSDKで公開するメリットがないのかもしれません。
まとめ
JawboneUP/UP24と連携するiOSアプリの実装方法について紹介しました。
上述したように現状ではサードパーティ製アプリではBLEで直接通信できないため、公式アプリでのデータ連携が前提となってしまいますが、UPPlatformではUP/UP24から取得できる運動データや睡眠データに加え、さらに体重データ・食事データや心臓データ等も統合的に扱えるので、アプリ開発の幅も広がるのではないでしょうか。