ページ

2014年6月14日土曜日

IBeacon開発に関する俺の勝手なまとめ

おはようございます、龍世(@rt1031_bot)です。


実はiOS7がリリースされて以降、僕は色々とiBeaconに触る機会があり、少ない時間でしたが、色々と試してみました。(もうiOS8が発表されましたが、この記事を書いた時は先々月くらいなのでまだでしたw


今回はその時に思った事や、こんな感じに書けばいいんじゃない?っていう僕なりのまとめです。





そもそもiBeaconってなんぞや




iBeaconってなんなん?って話から入ります。


これはiOS7から実装された機能で、iPhoneがBluetoothを利用して特定の電波を受信し、その電波を受信した事で何らかのアクションを起こしたりする事ができるのです。

そして、そのBluetoothを発信する機械をBeaconと呼びます。

またこのBeaconは、凄く小さい上にBluetooth Low EnergyBLE)と呼ばれる種類の電波を発信していまして、簡単に説明すると、かなり省エネでずーっと電波を発信しっぱなしでもボタン電池一つで1年くらいは動くよ!っという優れものでございます。(まぁ実際はBeaconの設定によって電池の持ちは大分変わってくるみたいですが。)


かなり砕いて説明したつもりなのですが、「わかりにくいよ、日本語不自由かよアホ!」という方はこちらのムービーをご覧下さい。イメージが掴めると思います(最初からそれでいいじゃねーかよ)




イメージは掴めましたか?

小さい岩みたいな形したEstimoteと言うBeaconが電波を発信し、iPhone側がそれを受信して30%SALEとかクーポンが表示されたりしていたと思います。

これがiBeaconです。

そして、この何かを表示させたりというのを実装していくのはアプリ側であり、僕がこの度色々試してみた点です。

では本題に入りたいと思います。




簡単なiBeacon観測




僕がiBeaconを始めた時、こちらの記事を参考にしました。


iBeacon Tips: 正しいビーコン監視方法



これらを踏まえて、iBeaconについて考えて行きたいと思います。



まず大事なのはiPhone側にBeaconを検知させる事です。

これには、CoreLocation.frameworkを利用するので、追加しておいて下さい。

では、まずは検知するBeaconのuuidの選択、そしてBeaconを受信すべくiPhone側から周りにBeaconがないか、周囲を観測させます。




まず、(Beaconの処理をしたいクラスの).hでこちらを定義

@interface ViewController () 

@property (nonatomic) CLLocationManager *locationManager;
@property (nonatomic) NSUUID *proximityUUID;
@property (nonatomic) CLBeaconRegion *beaconRegion;

@end


次に実装クラス(.m)の方に書いて行きます。

- (void)viewDidLoad {
    [super viewDidLoad];
    

[self.view addSubview:backImgae];

    
    if ([CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]]) {
        self.locationManager = [CLLocationManager new];
        self.locationManager.delegate = self;
        
        self.proximityUUID = [[NSUUID alloc] initWithUUIDString:@"自分が検知するビーコンのuuidを入れてね!"];
        
        self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:self.proximityUUID
                                                               identifier:@"com.zan-nen.IBEACONMASTER"];
        
        [self.locationManager startMonitoringForRegion:self.beaconRegion];
     //スタートモニタリング。つまり、ビーコンの観測の開始というメソッド。
    }
}

ここで大事なのが、CLLocationManagerクラスです。

isMonitoringAvailableForClassで、使用している端末でiBeaconが使えるかをチェックしています。(iPhone4S以降なら使えます)

またBeaconは20台まで登録出来るので、複数登録したい場合はこのif文の中に登録したい数だけ書けばおkです。


次に、startMonitoringForRegionメソッドで観測を開始します。





これにより、観測領域におけるイベントを処理する




観測が始まったらいよいよビーコンを検知し、イベントを起こしましょう!

どんなイベントでどんな処理をさせるかはアナタの発想しだい。そう、ここからが重要です。(タブンネー


CLLocationManagerDelegateプロトコルより、

- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
    [self.locationManager requestStateForRegion:self.beaconRegion];
    //ここが大事!!
}

ここが大事と書きましたが、これはiOS7から実装された、requestStateForRegionメソッドで、今現在、ビーコン観測がどういう状況なのかを教えてくれます。

これにより、次のイベントをハンドリングします。

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    switch (state) {
        case CLRegionStateInside: // 既にリージョン内にいる
            if ([region isMemberOfClass:[CLBeaconRegion class]] && [CLLocationManager isRangingAvailable]) {
                [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
            }
            NSLog(@"リージョンの中なのん");
            break;
        case CLRegionStateOutside:
        case CLRegionStateUnknown:
        default:
            break;
    }
}

// リージョン内に入ったら呼び出されるのん
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"リージョンに入ったのん");
}


          
          // リージョン観測範囲から出たら呼び出されるのん
          - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
    {
        NSLog(@"バイバイなんなー");
    }


//ビーコンのイベントをハンドリング
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
    if (beacons.count > 0) {
        CLBeacon *nearestBeacon = beacons.firstObject;
                
        switch (nearestBeacon.proximity) {
            case CLProximityImmediate:
                NSLog(@"凄く近いん");
                break;
            case CLProximityNear:
                NSLog(@"何気に近いのん");
                break;
            case CLProximityFar:
                NSLog(@"ちょっと遠いのん");
                break;
            default:
                NSLog(@"今日はここまでにしときます。さよならー");
                break;
        }



CLRegionStateInsideにより、リージョンの中に既にいるのかがわかります。(凄く重要)

そして、もしリージョンの中にいるのであれば、何らかの処理を施す事ができます。

※今回はビーコンとiPhoneの距離に応じてログが表示されるようにしています。

これが主な挙動です。



そして、これらを使って何をするかという点ですが、一番よく使うのは、Beaconを検知したら画面を推移するという事ではないでしょうか?


クーポンの表示で画面を切り替えたり、ビーコン検知で特殊なページに飛んだりという処理をする事が実用性が高いのではないかなぁ〜?という根拠です。






iBeaconを検知したら画面を切り替えるする




画面遷移の方法は色々ありますが、基本的にSBhさ使わずにコードで書いて行きます。

一番簡単なのは、画面を前後に入れ替えることだと思います。

これは本当に単純で、AppDelegateから遷移する二つの画面を生成し、

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    
    // create window
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    viewController1 = [[ViewController alloc] init];
    viewController2 = [[MovieViewController alloc] init];
    
    [self.window setRootViewController:viewController1]; //こっちが最初に表示される画面
    [self.window addSubview:viewController2.view];       //こっちがビーコンで切り替わる画面
    
    [self.window bringSubviewToFront:viewController1.view];
    [self.window sendSubviewToBack:viewController2.view];
    
    
    [self.window makeKeyAndVisible];
    return YES;
}

両画面を生成したら後はチョロくて、先ほどのイベントを処理しているSwitch文に、

switch (nearestBeacon.proximity) {
            case CLProximityImmediate:
                rangeMessage = @"Range Immediate: ";
                // この画面を背面へ
                [self.view.window sendSubviewToBack:self.view];
                NSLog(@"近いのん");
                break;


sendSubviewToBackメソッドで現在の画面を背面に持って行くと、元々背面にいた画面が前面に出てくるので、画面が切り替わる。

今回は以上。

発想しだいでiBeaconはショッピングだけでなく、ゲームなどにも使えると思います!

僕の場合はBtooomという漫画に出てくる手から出すレーダーをiBeaconを使って似たような物が作れないかな〜とか思っています。

後は、家にビーコンを置いておいて、帰宅すると、家に置いてあるビーコンに近づいたときにときに可愛い女の子が「おかえり!」って言ってくれるアプリとかくだらなくて作りたいな〜とか思っていますwwww




まぁこれからはSwiftの時代だし、iBeaconはSwiftでどんな風になっていくのかな?楽しみではありますね。

ってか早くSwiftの説明読んで勉強しなきゃw

ではまた!