いやなんか勢い余ってiOS Advent Calendarに申し込んでみたんですが、ほんと皆さん内容が充実すぎてまじすげーって感動してます!そんな僕はどうしようか悩んだんですが、ちょうど購入してからしばらく放置していたEstimote社のEstimote Beaconをいい加減触ってみたくって悶々としていたのでこれを触りつつ 7日目のネタにしようと思いました。
実はiBeaconのAdventCalendarも存在していて、内容だだかぶり感満載なんですが、もう後戻りできないのでこのネタでいっちゃいます!
Estimote Beacon 利用イメージ
一応リンク貼っときます。
http://www.youtube.com/watch?v=sUIqfjpInxY
Estimote Beacon
パッケージはかっこいいですね。なんかピーターモービルのUXハニカム構造を思い出したのは僕だけじゃないはず。
結構びっくりなのが、裏パッケージにCEOと思わしき人が手書きでサインしてくれてます。僕の名前も書いてます。届くのが遅かったのはこのせいでしょうか。
CEOでファウンダーのJakubの名刺です。若いですね。
一つのパッケージに3つ入ってます。色は選べなかったんですよね。
実物はこんな感じ。岩をモチーフにしたシリコン製の素材です。スイッチもなんもないです。ちなみに背面は粘着テープがついてて、壁とかに貼り付けたい場合は簡単に貼り付けられそうです。
で、 まずはSDKを使って開発する前に、Estimote Virtual Beacon ってサンプルアプリがEstimoteから提供されているのでこいつでEstimote Beaconの状態をみてみます。
いくつかデモがあります。適当に見てみました。
ちかくのEstimote Beaconが検出されます。2パッケージ入手したので合計6つですね。
詳細がみれる画面です。どうもEstimote BeaconのUUIDは"B9407F30-F5F8-466E-AFF9-25556B57FE6D" で一律固定みたいです。なので、検知する側は、上記UUIDで検索かけることで近隣のEstimoteBeaconを見つけることができるかもしれません。隣に住んでるギークな女子大生が使っているかもしれませんね。
すごく気になるのは、殆ど使ってないにもかかわらずBatteryLevelが62%とだいぶ減ってしまっている点です。どういうことでしょうか。電池の交換方法は不明です。
感度いまいちじゃね?問題
ここですごく気になったんですが、このEstimote Vertial Beacon のデモを使っていて最初に感じたのが、
なんか感度イマイチじゃね?
ってことです。感度イマイチ問題です。
こんなUIでEstimote BeaconとiPhone(黒点)の距離を見れるのですが、これがどうも全然機能していない。おそらく青い円が、中心から Immediate / Near / Far を示していると思うのですが、FarなのにImmediateっぽくみえたり、逆にImmediateなのにFarだったり。
このUIがあれば、どこかに隠されたEstimote Beaconを見つけるみたいなゲームができそうなのに、全然見つけられなかった。ここでちょっと、「あれ?まさかへんなの掴まされたんじゃね?会社のお金で買ったのにまずくね?」って焦る。
ひとまずSDK使ってみる
なんかサンプルアプリのバグの可能性もあるので、ひとまずSDK使って開発してみようと思います。
SDKダウンロード
EstimoteSampleプロジェクトを作成し、EstimoteSDKを組みこむ
Xcodeで"EstimoteSample"プロジェクトを作成します。その後、githubからダウンロードしたEstimoteSDKを追加します。
フレームワークの追加
以下のフレームワークを追加します。
- CoreBluetooth.framework
- CoreLocation.framework
- SystemConfiguration.framework
ジオフェンシングのサンプルコード
ベタなんですが、ジオフェンシングを利用し、入店・退店時に簡単な演出をするようなコードを書いてみました。
Estimote Beaconが、お店においてあるというシチュエーションで、
- 入店: いらっしゃいませ の声とともにローカルプッシュ
- 退店: ありがとうございました の声とともにローカルプッシュ
※アプリが起動中なら声、停止中もしくはバックグラウンドならローカルプッシュ。
というような演出です。
//
// ViewController.m
// EstimoteSample
//
// Created by Takatomo Okitsu on 2013/12/08.
// Copyright (c) 2013年 Takatomo Okitsu. All rights reserved.
//
#import "ViewController.h"
#import "ESTBeaconManager.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController () <ESTBeaconManagerDelegate>
@property (nonatomic, strong) ESTBeaconManager* beaconManager;
@property (nonatomic, strong) ESTBeacon* selectedBeacon;
@property (nonatomic, strong) AVSpeechSynthesizer* speechSynthesizer;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.beaconManager = [[ESTBeaconManager alloc] init];
self.beaconManager.delegate = self;
self.beaconManager.avoidUnknownStateBeacons = YES;
//特定のEstimote Beaconで固定にする。
ESTBeaconRegion* region = [[ESTBeaconRegion alloc] initRegionWithMajor:49220
minor:58122
identifier:@"B9407F30-F5F8-466E-AFF9-25556B57FE6D"];
[self.beaconManager startMonitoringForRegion:region];
[self.beaconManager requestStateForRegion:region];
_speechSynthesizer = [[AVSpeechSynthesizer alloc] init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)beaconManager:(ESTBeaconManager *)manager didDetermineState:(CLRegionState)state forRegion:(ESTBeaconRegion *)region
{
if (state == CLRegionStateInside) {
NSLog(@"inside now.");
} else if (state == CLRegionStateOutside){
NSLog(@"outside now.");
}
}
-(void)beaconManager:(ESTBeaconManager *)manager didEnterRegion:(ESTBeaconRegion *)region
{
[self say:@"いらっしゃいませ"];
// present local notification
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = @"いらっしゃいませ";
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
-(void)beaconManager:(ESTBeaconManager *)manager didExitRegion:(ESTBeaconRegion *)region
{
[self say:@"ありがとうございました"];
// present local notification
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = @"ありがとうございました。またのお越しをお待ちしております。";
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
-(void)say:(NSString*)text
{
AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:text];
[_speechSynthesizer speakUtterance:utterance];
}
@end
iOS7から追加されたAVSpeechUtteranceを使ったしゃべる演出は、以下のiBeacon AdventCalendarのものを参考にさせていただきました。面白いですね!
これで実機でアプリを起動すると、Estimote Beaconに5Mぐらい近づくと、いらっしゃいませのPush(もしくは声)が来て、今度は5Mぐらい離れるとありがとうございましたのPush(もしくは声)が来ました!
サンプルコード見てもらえるとわかるのですが、ESTBeaconManagerは、EstimoteSDKのクラスなのですが、ほぼほぼCLLocationManagerのラッパーです。他にもいくつかクラスありますが、これらもCoreLocationのなにかしらのクラスのラッパーです。EstimoteSDKでは何をやってるんだろうというぐらいに薄いです。Estimote Beaconのバッテリー状況取得するとか、いくつかハードウェア情報がAPI的に容易にとれるというだけで、あまりメリットはなさそうです。
ソースはgithubにあげときます。
https://github.com/okitsutakatomo/EstimoteSample
所感
本当に簡単なサンプルで恐縮ですが、使ってみてわかったことを書きます。
- NFCとかと比べると近距離での感度が悪い。特にproximityの値を判定した場合に、めちゃくちゃ近い距離なのに、3秒後ぐらいにやっとImmediateと判定されるレベル。これがiBeaconの仕様なのか、iOS7のCoreLocationAPIの制約なのか、EstimoteBeaconのハードのせいなのか不明。
- 正直このデバイスを実店舗で使って、満足するユーザ体験を提供できるかどうかだと微妙。
- iBeaconのiOSAPI自体はシンプル。EstimoteSDKの必要性はあまり感じない。