【Swift/iOS】iBeacon(ビーコン)の発信側(ペリフェラル)の実装方法
この記事からわかること
- SwiftでBeacon(ビーコン)を実装する方法
- iBeaconとは?
- 発信側(ペリフェラル)のiOSアプリの開発方法
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:15.0.1
- watchOS:10.0
- Swift:5.9
- macOS:Sonoma 14.1
ビーコン自体についてなどは以下の記事を参考にしてください。
SwiftでBeaconアプリを開発する
SwiftでBeaconアプリを開発するには発信用(ペリフェラル)と受信用(セントラル)どちらを開発するかをまず決めます。ほとんどの場合が受信用の開発になると思いますが、テストしたい場合に専用機器が用意できない場合などはSwiftで発信側も開発することでテストが容易に行えるようになります。
おすすめ記事:BLE(Bluetooth Low Energy)とは?セントラルやペリフェラルの意味と用語集
iBeaconでは発信する情報に以下の情報が含まれます。実装段階で必要になるので用意しておきます。
- UUID(16バイト):サービス識別子
- MAJOR(2バイト):任意の識別子(例:店舗内のセクション番号など)
- MINOR(2バイト):任意の識別子(例:店舗内のセクション内の棚番号など)
- RSSI(1バイト):デバイスとの距離(正確には信号の強さ)
発信用(ペリフェラル)の実装
公式リファレンス:Turning an iOS device into an iBeacon device
Beacon発信用(ペリフェラル)側を実装するにはCoreLocation/CoreBluetooth
を使用して実装できます。
実装の流れ
- BLE使用許可の追加
- CLBeaconRegionインスタンスを生成
- ペリフェラルとして動作を開始
- 電源ONになったらブロードキャスト開始
- アプリ起動時にBeaconを開始
受信用(セントラル)の実装方法は以下の記事を参考にしてください。
1.BLE使用許可の追加
Beaconを発信する側のアプリを実装するにはBLE機能の使用を許可しもらう必要があります。「info.plist」に以下の2つを追加し、使用する理由を記載しておきます。
- Privacy - Bluetooth Peripheral Usage Description:Bluetoothのペリフェラル機能の使用許可
- Privacy - Bluetooth Always Usage Description:Bluetooth機能の使用許可
2.CLBeaconRegionインスタンスを生成
CLBeaconRegion
でビーコン情報を保持したインスタンスを生成します。CLBeaconRegion
の引数にUUIDやMAJORなどを渡します。
static let PROXIMITY_UUID = UUID(uuidString: "00000000-0000-1111-1111-111111111111")!
static let MAJOR: CLBeaconMajorValue = 10
static let MINOR: CLBeaconMinorValue = 30
static let BEACON_ID = "BEACON"
/// CLBeaconRegionを生成
private func createBeaconRegion() -> CLBeaconRegion? {
return CLBeaconRegion(
uuid: BeaconPeripheralManager.PROXIMITY_UUID,
major: BeaconPeripheralManager.MAJOR,
minor: BeaconPeripheralManager.MINOR,
identifier: BeaconPeripheralManager.BEACON_ID
)
}
3.ペリフェラルとして動作を開始
生成したCLBeaconRegion
を元にNSDictionary
型のアドバタイズメントデータを生成しておきます。CBPeripheralManager
インスタンスを生成してペリフェラル(信号を送信する側)として動作開始できるようにしておきます。
/// Beaconをセットアップしペリフェラルとして登録
public func startBeacon() {
guard let localBeacon = createBeaconRegion() else { return }
// Beaconとして発信するために必要なデータ(アドバタイズメントデータ)を生成
beaconPeripheralData = localBeacon.peripheralData(withMeasuredPower: nil)
// デバイスをBluetoothペリフェラル(信号を送信する側)として動作開始
peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil)
}
4.電源ONになったらブロードキャスト開始
CBPeripheralManagerDelegate
のデリゲートメソッドからペリフェラルの電源がONになったタイミングでstartAdvertising
メソッドを使用しブロードキャスト開始します。
extension BeaconPeripheralManager: CBPeripheralManagerDelegate {
/// Peripheralの状態が変化するタイミングで呼ばれる
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
if peripheral.state == .poweredOn {
// ペリフェラルの電源がONになったタイミングでブロードキャスト開始
peripheralManager.startAdvertising(beaconPeripheralData as? [String: Any])
} else if peripheral.state == .poweredOff {
peripheralManager.stopAdvertising()
}
}
}
5.アプリ起動時にBeaconを開始
最後に任意のタイミング(今回はアプリ起動時)でBeaconを開始すればデータを発信する端末として動作するiOSアプリが完成です。
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
let beaconManager = BeaconPeripheralManager()
beaconManager.startBeacon()
return true
}
}
6.全体のコード
import CoreLocation
import CoreBluetooth
class BeaconPeripheralManager: NSObject, CLLocationManagerDelegate {
private var localBeacon : CLBeaconRegion!
private var beaconPeripheralData: NSDictionary!
private var peripheralManager: CBPeripheralManager!
static let PROXIMITY_UUID = UUID(uuidString: "00000000-0000-1111-1111-111111111111")!
static let MAJOR: CLBeaconMajorValue = 10
static let MINOR: CLBeaconMinorValue = 30
static let BEACON_ID = "BEACON"
/// CLBeaconRegionを生成
private func createBeaconRegion() -> CLBeaconRegion? {
return CLBeaconRegion(
uuid: BeaconPeripheralManager.PROXIMITY_UUID,
major: BeaconPeripheralManager.MAJOR,
minor: BeaconPeripheralManager.MINOR,
identifier: BeaconPeripheralManager.BEACON_ID
)
}
/// Beaconをセットアップしペリフェラルとして登録
public func startBeacon() {
guard let localBeacon = createBeaconRegion() else { return }
// Beaconとして発信するために必要なデータ(アドバタイズメントデータ)を生成
beaconPeripheralData = localBeacon.peripheralData(withMeasuredPower: nil)
// デバイスをBluetoothペリフェラル(信号を送信する側)として動作開始
peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil)
}
/// Beaconを停止
private func stopBeacon() {
peripheralManager.stopAdvertising()
localBeacon = nil
beaconPeripheralData = nil
peripheralManager = nil
}
}
extension BeaconPeripheralManager: CBPeripheralManagerDelegate {
/// Peripheralの状態が変化するタイミングで呼ばれる
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
if peripheral.state == .poweredOn {
// ペリフェラルの電源がONになったタイミングでブロードキャスト開始
peripheralManager.startAdvertising(beaconPeripheralData as? [String: Any])
} else if peripheral.state == .poweredOff {
peripheralManager.stopAdvertising()
}
}
}
このデモプロジェクトはGitHubにあげていますので参考にしてください。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。