JSでiBeaconを試せるiOSアプリ「BeaconEgg」の使い方

[2013年のアドベントカレンダー](http://qiita.com/naonya3/items/a4a07d6a334717f8d83d)用に作ったアプリなのですが、紆余曲折あってようやくリリース出来ました。

[BeaconEgg - App Store](https://itunes.apple.com/us/app/beaconegg-ibeacon-developer/id828466802?mt=8)

## BeaconEggの簡単な説明
一行で説明すると

[BeaconEgg.js](https://github.com/adhr/BeaconEgg)という専用のライブラリを使いWEBコンテンツを制作し<br />
BeaconEggアプリ上でそのコンテンツを開けば、iBeaconの機能にアクセスできるようになるよ！

というものです。（二行）

## できること

BeaconEgg.jsで作成したデモがあるので、そちらを見ていただけると理解しやすいと思います。

デモが動いている動画はこちらです。

<iframe src="//player.vimeo.com/video/91167019" width="500" height="281" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe> <p><a href="http://vimeo.com/91167019">BeaconEgg - Demo</a> from <a href="http://vimeo.com/naotohoriguchi">Naoto Horiguchi</a> on <a href="https://vimeo.com">Vimeo</a>.</p>

## できないこと

- Backgroundで動作しない（はず）

## デモのコードを解説
[デモで使用したコードがこちらです。](https://github.com/adhr/BeaconEgg/blob/gh-pages/sample.html)

ざっくり説明していきます。

まず、48行目でBeaconEggのインスタンスを作っています。

```js:
var be = new adhr.BeaconEgg,
```

次に49行目で監視対象のリージョンを指定します。

```js:
region = new adhr.Region('jp.adhr.beacon-egg', '1E21BCE0-7655-4647-B492-A3F8DE2F9A02'),
```

第一引数がid(なんでもいい)、第二引数がリージョンのUUIDです。

最後に100行目で指定リージョンのモニタリングを開始します。

```js:
be.startMonitoring(region);
```

以上で使用準備が整いました。

**次にBeaconを見つけた際に呼ばれる各イベントを見ていきます。**

58行目から始まる`enterRegion`は、指定リージョン内に入った際に呼ばれます。ざっくり言うと指定したUUIDを持っているbeaconが発している電波をキャッチしたら呼ばれます。

```js:
be.enterRegion(function(region) {
    alert('Enter Region!!')
});
```

この例ではAlertを表示しているだけです。

65行目は`enterRegion`の逆で、リージョンから離れた際に呼ばれます。ざっくり言うと、beaconの電波をキャッチできなくなって20−30秒すると呼ばれます。

```js:
be.exitRegion(function(region) {
    alert('Exit Region!!')
});
```

なぜ20-30秒かかるかというと、例えばbeaconの電波が障害物などでブツブツ切れてるだけなのにいちいち接続を切っていたら大変だろ？っていうAppleさんの心遣いだと思います。確実にリージョン外に出たことがわかってから呼ばれます。

72行目からの`renge`は`enterRegion`が呼ばれてから`exitRegion`が呼ばれる間に電波をキャッチ出来ているbeacon端末の情報が配列で渡されます。

だいたい１秒間隔くらいで更新されるようです。

配列内の各beaconオブジェクトから詳細な情報が取得できます。

```js:
be.range(function(beacons) {
    var beacon = beacons[0];
    switch(true) {
        case beacon.isImmediate()://beaconはすごい近い
            document.body.style.backgroundColor = 'rgb(199, 43, 43)';
            break;
        case beacon.isNear()://beaconは割と近い
            document.body.style.backgroundColor = 'rgb(199, 199, 43)';
            break;
        case beacon.isFar()://beaconは遠い
            document.body.style.backgroundColor = 'rgb(74, 199, 43)';
            break;
        case beacon.isUnKnown()://よくわかんなくなっちゃった
            document.body.style.backgroundColor = 'rgb(43, 193, 199)';
            break;
        default:
            document.body.style.backgroundColor = '#ff961f';
    }
    rssiElm.innerHTML     = 'rssi: ' + beacon.rssi;//rssi
    accuracyElm.innerHTML = 'accuracy: ' + beacon.accuracy;//accuracy
    majorElm.innerHTML    = 'major: ' + beacon.major;//major id
    minorElm.innerHTML    = 'minor: ' + beacon.minor;//minor id
});
```

このように簡単にiBeaconを使ったコンテンツをJSで作ることができます。

あとは、コンテンツを公開し、BeaconEgg上でURLを入力して開くだけです。
アプリ上でURLを入力するのが億劫な人の為にURLScheme`beaconegg://egg/open?url=(URL)`も用意していますので、もし良かったらお使いください。

## おまけ

iBeaconの端末を持っていない方の為に、BeaconEggにはお使いのiPhoneをiBeacon端末にする機能`iBeaconSender`が搭載されています！

<iframe src="//player.vimeo.com/video/91172591" width="500" height="281" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe> <p><a href="http://vimeo.com/91172591">BeaconEgg - iBeaconSender</a> from <a href="http://vimeo.com/naotohoriguchi">Naoto Horiguchi</a> on <a href="https://vimeo.com">Vimeo</a>.</p>

当初予定していない機能だったのですが、[いろいろあって](http://qiita.com/naonya3/items/a4a07d6a334717f8d83d#1-4)実装いたしました。

デモで使っているリージョンのbeaconもプリセットで入っています。

**100円です。**

他にもiPhoneをiBeacon端末にできるフリーで素晴らしいアプリが色々とストアで公開されていますが、 **察してください** 。

リージョン毎にbeaconを複数管理できるようになっているので、開発には便利かもしれません。

## 謝辞（懺悔）
デモコンテンツ開発の際に、iBeacon端末側にクラスメソッド様の[ Mac を Beacon 端末にする](http://dev.classmethod.jp/smartphone/iphone/mac-beacon/)の記事のMacアプリを使わせて頂きました。ありがとうございます。

ここから懺悔なのですが、UUIDを変更したつもりが、うっかりデモコンテンツで同じUUIDを指定してしまいました。大変失礼いたしました、、、

なので、BeaconEggのデモコンテンツは記事で紹介されているMacアプリでそのまま動かすこともできますよ！（ごめんなさいごめんなさい）