EstimoteSDKを使ってみた

いやなんか勢い余ってiOS Advent Calendarに申し込んでみたんですが、ほんと皆さん内容が充実すぎてまじすげーって感動してます！そんな僕はどうしようか悩んだんですが、ちょうど購入してからしばらく放置していたEstimote社のEstimote Beaconをいい加減触ってみたくって悶々としていたのでこれを触りつつ 7日目のネタにしようと思いました。
実はiBeaconのAdventCalendarも存在していて、内容だだかぶり感満載なんですが、もう後戻りできないのでこのネタでいっちゃいます！

# Estimote Beacon 利用イメージ
一応リンク貼っときます。
http://www.youtube.com/watch?v=sUIqfjpInxY



# Estimote Beacon

http://estimote.com/

パッケージはかっこいいですね。なんかピーターモービルのUXハニカム構造を思い出したのは僕だけじゃないはず。

![IMG_0552.JPG](https://qiita-image-store.s3.amazonaws.com/0/20486/ec462fd9-757b-06b6-d595-deca4abccb07.jpeg "IMG_0552.JPG")

結構びっくりなのが、裏パッケージにCEOと思わしき人が手書きでサインしてくれてます。僕の名前も書いてます。届くのが遅かったのはこのせいでしょうか。

![IMG_0554.JPG](https://qiita-image-store.s3.amazonaws.com/0/20486/697a079f-29ad-ba79-0e68-b936aca516e1.jpeg "IMG_0554.JPG")


CEOでファウンダーのJakubの名刺です。若いですね。

![IMG_0556.JPG](https://qiita-image-store.s3.amazonaws.com/0/20486/d8a41368-c048-8682-f9d9-98e01da1e9f6.jpeg "IMG_0556.JPG")

一つのパッケージに3つ入ってます。色は選べなかったんですよね。

![IMG_0559.JPG](https://qiita-image-store.s3.amazonaws.com/0/20486/61bf6091-4dcb-e328-6564-dad005863874.jpeg "IMG_0559.JPG")

実物はこんな感じ。岩をモチーフにしたシリコン製の素材です。スイッチもなんもないです。ちなみに背面は粘着テープがついてて、壁とかに貼り付けたい場合は簡単に貼り付けられそうです。

![IMG_0562.JPG](https://qiita-image-store.s3.amazonaws.com/0/20486/3f17a199-852d-e68f-ea8e-da1d96f281fe.jpeg "IMG_0562.JPG")


で、 まずはSDKを使って開発する前に、Estimote Virtual Beacon ってサンプルアプリがEstimoteから提供されているのでこいつでEstimote Beaconの状態をみてみます。

https://itunes.apple.com/us/app/estimote-virtual-beacon/id686915066

![IMG_0566.PNG](https://qiita-image-store.s3.amazonaws.com/0/20486/390d158a-4d28-019f-aa00-d7291d9cfabb.png "IMG_0566.PNG")

いくつかデモがあります。適当に見てみました。

![IMG_0572.PNG](https://qiita-image-store.s3.amazonaws.com/0/20486/0cd504b5-e5d5-2e17-46f2-ec0c53f0bc1b.png "IMG_0572.PNG")

ちかくのEstimote Beaconが検出されます。2パッケージ入手したので合計6つですね。

![IMG_0573.PNG](https://qiita-image-store.s3.amazonaws.com/0/20486/c2c98330-1e6a-8f09-a37e-7d0ef711013d.png "IMG_0573.PNG")

詳細がみれる画面です。どうもEstimote BeaconのUUIDは"B9407F30-F5F8-466E-AFF9-25556B57FE6D" で一律固定みたいです。なので、検知する側は、上記UUIDで検索かけることで近隣のEstimoteBeaconを見つけることができるかもしれません。隣に住んでるギークな女子大生が使っているかもしれませんね。

![IMG_0574.PNG](https://qiita-image-store.s3.amazonaws.com/0/20486/2adbb4c7-d955-cb1a-29b7-6f946d08afeb.png "IMG_0574.PNG")

すごく気になるのは、殆ど使ってないにもかかわらずBatteryLevelが62%とだいぶ減ってしまっている点です。どういうことでしょうか。電池の交換方法は不明です。


# 感度いまいちじゃね？問題

ここですごく気になったんですが、このEstimote Vertial Beacon のデモを使っていて最初に感じたのが、
**なんか感度イマイチじゃね？**
ってことです。感度イマイチ問題です。

![IMG_0575.PNG](https://qiita-image-store.s3.amazonaws.com/0/20486/1b87c78d-b11b-8994-c91e-26f6aacd8243.png "IMG_0575.PNG")


こんなUIでEstimote BeaconとiPhone（黒点）の距離を見れるのですが、これがどうも全然機能していない。おそらく青い円が、中心から Immediate / Near / Far を示していると思うのですが、FarなのにImmediateっぽくみえたり、逆にImmediateなのにFarだったり。
このUIがあれば、どこかに隠されたEstimote Beaconを見つけるみたいなゲームができそうなのに、全然見つけられなかった。ここでちょっと、「あれ？まさかへんなの掴まされたんじゃね？会社のお金で買ったのにまずくね？」って焦る。

# ひとまずSDK使ってみる

なんかサンプルアプリのバグの可能性もあるので、ひとまずSDK使って開発してみようと思います。

## SDKダウンロード

https://github.com/Estimote/iOS-SDK

## EstimoteSampleプロジェクトを作成し、EstimoteSDKを組みこむ

Xcodeで"EstimoteSample"プロジェクトを作成します。その後、githubからダウンロードしたEstimoteSDKを追加します。

![EstimoteSample.xcodeproj.png](https://qiita-image-store.s3.amazonaws.com/0/20486/23b71226-5664-99e9-d021-8afca8be3e5e.png "EstimoteSample.xcodeproj.png")


## フレームワークの追加
以下のフレームワークを追加します。

- CoreBluetooth.framework
- CoreLocation.framework
- SystemConfiguration.framework

![EstimoteSample.xcodeproj.png](https://qiita-image-store.s3.amazonaws.com/0/20486/cb38cd38-ac7a-721d-879b-da4c0ce814c0.png "EstimoteSample.xcodeproj.png")


## ジオフェンシングのサンプルコード
ベタなんですが、ジオフェンシングを利用し、入店・退店時に簡単な演出をするようなコードを書いてみました。
Estimote Beaconが、お店においてあるというシチュエーションで、
- 入店: いらっしゃいませ の声とともにローカルプッシュ
- 退店: ありがとうございました の声とともにローカルプッシュ
※アプリが起動中なら声、停止中もしくはバックグラウンドならローカルプッシュ。
というような演出です。

```objectivec:ViewController.m
//
//  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のものを参考にさせていただきました。面白いですね！

http://qiita.com/youten_redo/items/7d0856bc521b19778c96

これで実機でアプリを起動すると、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の必要性はあまり感じない。