RubymotionでiBeaconを使ってみた


とあるハッカソンイベントで今更ながらbeaconを使ったアプリをrubymotionで作ってみた。
途中自分のiphoneが原因でつまずいた部分があったが、結構簡単だったのでまとめておく。

###概要
・rubymotionで作ったアプリからiBeaconの電波を発信
・nodeで作ったアプリを立ち上げておいてiBeaconの電波をキャッチ
※これ以上はハッカソンのネタバレになるので...w

ちなみに下記の記事が参考になった。

#####・rubymotion

[RubyMotionでiBeacon]
(http://qiita.com/mackato/items/ff9c3afb819dfc54cf54)

[iOS7 で iBeacon を使用してみよう ~応用編~]
(http://www.gaprot.jp/pickup/ibeacon/ibeacon-vol2/)

[iBeacon開発ハマリどころポイントまとめ]
(http://qiita.com/himara2/items/1d6c11a4d4839c3027d5)

[【連載】Bluetooth LE (3) iOS デバイスを Bluetooth LE 機器にする](http://blog.fenrir-inc.com/jp/2013/10/bluetooth-le-ios-2.html)


#####・mac
[たった5行!最も簡単にiBeaconの電波を「受信」する方法]
(http://qiita.com/Morikuma_Works/items/c2899e548da1c5e2c28e)


###iBeaconを使う上で、理解しておいた方が良い事

(i)単語系

| 単語 | 概要 |
|:-----------|------------:|
| UUID  |        ビーコン又はグループを識別するID。macだとuuidgenで作成したりすれば良い。|
| major     |      UUIDが同じビーコンを識別するために使う。16ビットの符号無し整数値が設定できる。|
| minor     |      UUID/majorが同じビーコンを識別するために使う。16ビットの符号無し整数値が設定できる。|


(ii)使用上の注意
・ios7以上じゃないと使えませんw
(※androidは4.3以降)
→ただ今後出るものは基本対応できると思うので、大丈夫かと。


・Bluetoothをonにしてないと使えませんw
→消費電力がかなり抑えられるようになったので,iwatchをはじめ、基本onの状態のデバイスが増えるはず。

・受信はバックグラウンドでもできますが、発信はできませんw
→受信できるんだったら今後発信もできるだろうとか思ってます。。。

###実装する前に試してみた方が良い事

####・そもそも自分のiphoneでBeaconの電波が受信できるかどうか？
自分は結構iphoneが外傷によりボロボロなので、その辺機能しているかを先に確認しました。

#####(i)ios7以上のデバイスが2つある場合

Beaconの電波を感知できる/Beaconの電波を発信できるアプリがAppstoreに多く存在します。

例) Broadcast, BLUETUS fot iBeacon etc...
※リンク無くてすみません

上記を使ってデバイス間で発信→受信をやってみてください

#####(ii)ios7以上のデバイスが1台の場合
MacからBeaconの電波を飛ばす事が可能です。

下記のリンクをみてやってみて下さい。

[[iOS 7] [iBeacon] Mac を Beacon 端末にする](http://dev.classmethod.jp/smartphone/iphone/mac-beacon/)


###実装
※node側は省略

まずは必要なフレームワークを追加します。
iBeaconには'CoreLocation', 'CoreBluetooth'が必要なのでその2つを追加します。

```Rakefile
Motion::Project::App.setup do |app|
  app.frameworks += ['CoreLocation', 'CoreBluetooth']
end
```

```app/controllers/beacon_controller.rb
class BeaconController < UIViewController
  
  def viewDidLoad
    super
    #画面の作成
    view.backgroundColor = UIColor.colorWithRed(0.29, green: 0.29, blue: 0.29, alpha:0.8)
    @label = UILabel.alloc.init
    @label.textAlignment = NSTextAlignmentCenter
    @label.text = "Now, send the beacon ..."                                                                                                                                                   
    @label.frame = [[0, 100], [320, 100]]
    @label.font = UIFont.fontWithName("Hiragino Kaku Gothic ProN W3", size:20)
    @label.textColor = UIColor.whiteColor
    self.view.addSubview(@label)

    #Beaconで使うUUIDの設定
    @uuid = NSUUID.alloc.initWithUUIDString("※macだとuuidgenを実行した時の値で良いかと思います")

    #領域観測の対象となる Beacon を表すクラス
    @region = CLBeaconRegion.alloc.initWithProximityUUID(@uuid, major: 100006, minor: 2, identifier: "moriyaman")
    #Peripheral側を管理するクラス
    @manager = CBPeripheralManager.alloc.initWithDelegate(self, queue: Dispatch::Queue.main.dispatch_object)
  end 

  def peripheralManagerDidUpdateState(peripheral)
    #Bluetooth Low Energyが利用可能になったとき
    if peripheral.state == CBPeripheralManagerStatePoweredOn
      @manager.startAdvertising @region.peripheralDataWithMeasuredPower(nil)
    end 
  end 

end

```

[CLBeaconRegionのリファレンス](https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLBeaconRegion_class/Reference/Reference.html)

[CBPeripheralManager クラス リファレンス 日本語訳](http://reinforce-lab.github.io/blog/2013/01/28/cbperipheralmanager-classreference-jp/)


Bluetooth Low Energyでは，端末がCentralとPeripheralの２つに分かれます。今回の場合だとiphoneアプリで発信を行うので、Peripheral側という事です。
(※市販のBeaconを使った場合だと、iphoneがCentral側ですね。)

上記で書いているので分かると思いますが、
CBPeripheralManagerクラスでPeripheral側を制御しています。

```
rake device
```

で実機に転送してテストをすると無事、nodeのアプリ側で取得できました♩

![Default-568h@2x.png](https://qiita-image-store.s3.amazonaws.com/0/5365/eb5f6b33-886e-99ff-93ba-516ac85e2c8b.png)