JINS MEME
いわゆるライフログ系のウェアラブルデバイスをメガネにしたもの。リストバンドタイプのものが多いよね。
メガネなので、加速度や傾きを頭部で測れるという面白さがある。
あと眼電位を測れて、眼の動きやまばたきを検出できる(ESモデルのみ)。
2015/11/05に発売。発売時からiOS用SDKが配布されており、計測データを使ったアプリ開発が可能。
Android向けSDKも年明けに出るとか。
概要
というわけで、早速iOSアプリ作るよ。
環境
- Xcode 7.1 (El Capitan)
- iPhone 6
- iOS 9.1
- JINS MEME ES
- JINS MEME SDK 1.0.5
手順
Project作成
ウィザードに従って、こんな感じで。
- Single View Application
- Language: Swift
- Devices: iPhone
SDK導入
上記ページからSDKをダウンロード
開発用とApple申請用の2種類のフレームワークがあるので、開発用を使う。
framework/universal/MEMELib.framework
を、作成したプロジェクトのディレクトリにコピー。
更に、コピーした上記ファイル(実体はディレクトリ)を、Xcodeの Embedded Binaries
にドラッグ&ドロップ。
Bluetooth権限設定
Capabilities > Background ModesをONにし、 Use Bluetooth LE accessory
にチェック。
Bridging Headerファイル作成
プロジェクトに新規headerファイルを作成し、以下のimport文を記述。
#import <MEMELib/MEMELib.h>
さらに、Build Settings > Swift Compiler - Code Generationに、Bridging Headerファイルパスを指定。
アプリケーション認証コード発行
上記ページからアプリケーション登録する。
登録すると、アプリ一覧ページに表示される。
「詳細・編集」ボタンを押すと、アプリケーション認証コードを確認できる。
コード記述
アプリケーション認証
AppDelegate.swift
に以下を記述。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
MEMELib.setAppClientId("<発行されたアプリID>", clientSecret: "<発行されたアプリSecret>")
return true
}
以後、 MEMELib.sharedInstance()
に対して各種処理をコールしていくが、1回目の sharedInstance()
取得の前にこのアプリ認証情報設定が必要。
JINS MEMEに接続して、データを取得
ここでは、エラー処理とか、あらゆるパターンを考慮したライフサイクル管理とか一切省略。動かすことに専念する。
ViewController.swift
を以下のような感じに。
import UIKit
class ViewController: UIViewController, MEMELibDelegate {
override func viewDidLoad() {
super.viewDidLoad()
MEMELib.sharedInstance().delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func memeAppAuthorized(status: MEMEStatus) {
MEMELib.sharedInstance().startScanningPeripherals()
}
func memePeripheralFound(peripheral: CBPeripheral!, withDeviceAddress address: String!) {
MEMELib.sharedInstance().connectPeripheral(peripheral)
}
func memePeripheralConnected(peripheral: CBPeripheral!) {
let status = MEMELib.sharedInstance().startDataReport()
print(status)
}
func memeRealTimeModeDataReceived(data: MEMERealTimeData!) {
print(data.description)
}
}
-
MEMELibDelegate
をimplement -
MEMELib
インスタンスのdelegate
プロパティに自身を代入し、各種イベントが通知されるように - 1回目の
sharedInstance()
コール時にアプリ認証が走り、成功したらmemeAppAuthorized
が呼ばれる-
startScanningPeripherals()
をコールし、BT接続済みのJINS MEMEを探す - このコードは一応、事前に公式アプリでBT接続しておく前提
-
- JINS MEMEが見つかったら
memePeripheralFound
が呼ばれる-
connectPeripheral(peripheral)
をコールし、アプリ - JINS MEME間接続を試みる
-
- アプリとJINS MEMEが接続されたら、
memePeripheralConnected
が呼ばれる-
startDataReport()
をコールすると、定期的にデータが取得され・・・るはず - なんだけど、 データ取得開始しませんw
- このコードみたく、
startDataReport()
の戻りをチェックすると、確かに失敗コードが返る - あと、以下の様なエラーが出る
-
JinsQiita[5749:2461884] MEME Model Type Check: error = [(null)], errorDescription = [(null)]
startDataReport()
がもし成功していたら、データが memeRealTimeModeDataReceived
に流れてくるはず。
というわけで、動かない
フォーラム見てみたら、同じエラー出てる人いた。
ので、ちょいと様子見。
動いた人いたら教えてくださいmm
2015-11-09 追記
動いた!
フォーラムから引用
JINSMEMEからのデータ送信中は、
データモードの変更を許可しない仕様としております。
弊社Officialアプリは、スタンダードモードを利用しており、
このモードでデータ送信中の場合に当現象が発生致します。
弊社Officialアプリを起動しない状態にて、
JINSMEMEに接続し、ご利用いただけますでしょうか。
公式アプリは「スタンダードモード」で動いてるが、独自アプリは「リアルタイムモード」になる。
で、両モードを同時には動かせないということらしい。
うまく公式アプリ側を止めてやるとちゃんと動くとのことだが、この記事のコードだと1つ問題がある。
-
startScanningPeripherals()
を実行するときには、公式アプリで繋がっていないといけない。
本記事のコードは startScanningPeripherals()
から startDataReport()
までノンストップで実行するようになっているので、その間に公式アプリを止めるタイミングがないということになる。
connectPeripheral()
のコールは無条件で走らせずに、タップなどのユーザイベントをフックする形にすれば回避できるが、今のコードのままで動作させる手順もあったので、記載しておく。
- 公式アプリ側の設定画面で一度JINS MEMEを切断
- 設定画面で再接続
- その後、公式アプリは、ホームやライブビューに遷移せず、そのまま閉じる
- 自作アプリを起動
この手順だと、公式アプリの「スタンダードモード」が起動しないのだと思われる。