質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

解決済

iOS同士のBLE通信、connect方法

saku_panda
saku_panda

総合スコア20

Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

1回答

0リアクション

0クリップ

3513閲覧

投稿2019/10/29 02:57

編集2019/10/29 04:22

##前提・実現したいこと
iOS同士のセントラル、ペリフェラルの接続(connect)

##発生している問題
おそらくセントラルのスキャンが上手く機能していません。
ログ出しで確認しましたが、
centralManager.scanForPeripherals のメソッドには入っています。
しかしその先のcentralManager(:didDiscover::_)のログが表示されず、ペリフェラルを一つも検知していません。
上記判断の根拠として、ログ出しの他に、
ペリフェラル側は peripheralManagerDidStartAdvertisingを成功させており、
nordic社の nRF Connect でアドバタイズを飛ばしていることも確認できたからです。

##該当のソースコード

Swift5

// セントラル側 import Foundation import CoreBluetooth // セントラルマネージャーのデリゲートとペリフェラルマネージャーを持つ class CentralService: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate { private let Log = Logger(category: "Central" )! // オリジナルUUID。 static let serviceUUID: CBUUID = CBUUID(string: "566F2065-450F-4633-0123-456789ABCDEF") var serviceUUIDList: [CBUUID] = [serviceUUID] static let charReadUUID: CBUUID = CBUUID(string: "A1F86134-652D-1234-0123-456789ABCDEF") static let descriptorUUID: CBUUID = CBUUID(string: "97A4D0DD-1556-4454-0123-456789ABCDEF") static let charNotifyUUID: CBUUID = CBUUID(string: "A1F86134-652D-1234-FEDC-BA9876543210") var centralManager: CBCentralManager? // センタラルマネージャーのインスタンス var peripherals: [CBPeripheral] = [] // CBPeripheral型の配列.見つけ出したペリフェラルを一時保存する var cbPeripheral: CBPeripheral? = nil // ペリフェラルマネージャーのインスタンス var readCharacteristic: CBCharacteristic? = nil // メッセージ読み取りのキャラクタリスティック var notifyCharacteristic: CBCharacteristic? = nil // メッセージ読み取り可能通知のキャラクタリスティック var mssLen: Int = 0 var VC :ViewController? = nil // 初期化 override init () { super.init() Log.i("init") // serviceUUIDList = [CentralService.serviceUUID] centralManager = CBCentralManager(delegate: self, queue: nil) } func centralManagerDidUpdateState(_ central: CBCentralManager) { switch (central.state) { case .poweredOn: Log.i("BLE Power On") scanStart() case .poweredOff: Log.i("BLE Power off") break case .resetting: Log.i("BLE resetting") break case .unauthorized: Log.i("BLE unauthorized") break case .unknown: Log.i("BLE unknown") break case .unsupported: Log.i("BLE unsupported") break @unknown default: Log.i("BLE unknown Default") break } } // サービスUUID検索 func scanStart() { Log.i("scan start") /* 重複フィルタリングの設定、 trueなら同じPeripheralからのアドバタイズで毎回イベント発生させる ※このフィルタリングを利用するとバッテリーの消耗を抑えられる */ let options = [CBCentralManagerScanOptionAllowDuplicatesKey : true] if centralManager!.isScanning == false { // 探し出すサービスのUUIDを配列に入れて指定する. let UUIDArray :[CBUUID] = [CentralService.serviceUUID] Log.d("UUIDArray = (UUIDArray)") /* scanForPeripherals(withServices @param withServices: [CBUUID]? 検索するCBUUIDを集めたの配列。 options: nil オプション */ centralManager!.scanForPeripherals(withServices: UUIDArray, options: options) } } /* ペリフェラル発見時に呼び出される @param central: CBCentralManager セントラルマネージャー peripheral: CBPeripheral 発見したペリフェラル advertisementData: [String : Any] 発見したペリフェラルの広告 rssi RSSI: NSNumber 発見したペリフェラルのRSSI */ func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { Log.i("append Peripheral") /* 見つけ出したペリフェラルを配列に入れて保存する */ peripherals.append(peripheral) connect() } /* 検索したペリフェラルとコネクト(ペアリング)する */ func connect() { Log.d("connect") // 見つけ出したペリフェラル全てを調べる for peripheral in peripherals { // ペリフェラルの名前が一致したら if ((peripheral.name != nil) && (peripheral.name == "Test Device")) { cbPeripheral = peripheral centralManager?.stopScan() Log.d("scan stopped") break } } // 上のループでペリフェラルを見つけられていたらコネクトする if (cbPeripheral != nil) { centralManager!.connect(cbPeripheral!, options: nil) } } /*****************  以下長いので省略 ******************/

###セントラルのログ
[Central] [INF] init
[Central] [INF] BLE Power On
[Central] [INF] scan start
[Central] [DEB] isScanning == false in
[Central] [DEB] UUIDArray = [566F2065-450F-4633-0123-456789ABCDEF]

###該当ソースコード

Swift5

// ペリフェラル側 import Foundation import CoreBluetooth class PeripheralService: NSObject, CBPeripheralManagerDelegate { private let Log = Logger(category: "Peripheral" )! var myPeripheralManager: CBPeripheralManager? let advertisementData = [CBAdvertisementDataLocalNameKey: "Test Device"] // アドバタイズに乗せるデータ static let serviceUUID: CBUUID = CBUUID(string: "566F2065-450F-4633-0123-456789ABCDEF") static let characteristicUUID: CBUUID = CBUUID(string: "A1F86134-652D-1234-0123-456789ABCDEF") static let descriptorUUID: CBUUID = CBUUID(string: "97A4D0DD-1556-4454-0123-456789ABCDEF") static let charNotifyUUID: CBUUID = CBUUID(string: "A1F86134-652D-1234-FEDC-BA9876543210") // サービスの設定、UUIDと let service = CBMutableService(type: PeripheralService.serviceUUID, primary: true) // プロパティの設定、このキャラクタリスティックに対して何ができるかを設定している let readProperties: CBCharacteristicProperties = [.read] // 認可の設定、キャラクタリスティックの読み取り、書き込み、暗号化の認可 let permissions: CBAttributePermissions = [.readable] // キャラクタリスティックが属するサービスと、プロパティおよびその認可を設定 var characteristic: CBMutableCharacteristic? = nil var requestList: [CBATTRequest] = [] // 初期化 override init () { super.init() Log.i("init") myPeripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil) } func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { switch peripheral.state { case .poweredOn: Log.i("bluetooth Success") characteristic = CBMutableCharacteristic(type: PeripheralService.characteristicUUID, properties: readProperties, value: nil, permissions: permissions) setService_Charactaristic() case .unknown: Log.i("bluetooth error") case .resetting: Log.i("bluetooth error") case .unsupported: Log.i("bluetooth error") case .unauthorized: Log.i("bluetooth error") case .poweredOff: Log.i("bluetooth error") @unknown default: Log.i("bluetooth error") } } func setService_Charactaristic(){ Log.i("set Service and Characteristic") // キャラクタリスティックが属するサービスと、プロパティおよびその認可を設定 characteristic = CBMutableCharacteristic(type: PeripheralService.characteristicUUID, properties: readProperties, value: nil, permissions: permissions) // 作成したサービスのキャラクタリスティックに、作成したキャラクタリスティックを設定 // 設定は配列で複数個所持できる service.characteristics = [characteristic!] // ペリフェラルへ上記サービスを設定 myPeripheralManager?.add(service) advStart() } // アドバタイズ開始 func advStart(){ Log.i("Start Advetising") myPeripheralManager!.startAdvertising(advertisementData) } /* peripheralManager(_: didAddService:_) addServiceメソッドを呼び出してローカル周辺機器のGATTデータベースにサービスを公開すると、 Core Bluetoothがこのメソッドを呼び出します peripheralManager:(CBPeripheralManager *)peripheral //サービスを追加したペリフェラル didAddService:(CBService *)service // GATTデータベースへ追加されたサービス error:(NSError *)error; //失敗したエラー理由 失敗しなかった場合nilが入る */ func peripheralManager(peripheral: CBPeripheralManager, didAddService service: CBService, error: NSError?) { if error != nil { Log.i("サービス追加失敗! error: (error!)") return } else { myPeripheralManager!.stopAdvertising() Log.i("Stop Advertising") } } /* peripheralManagerDidStartAdvertising アドバタイズが正常に開始できたかを確認 @param peripheral: CBPeripheralManager アドバタイズを始めるペリフェラル error: NSError? 失敗理由。失敗しなかった(成功した)場合はnil */ func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) { if (error != nil) { Log.i("Advertise Failed error: (error!)") return } else { Log.i("Advertise Succeeded!") } } /*****************  以下長いので省略 ******************/

ペリフェラルのログ

[Peripheral] [INF] init
[Peripheral] [INF] bluetooth Success
[Peripheral] [INF] set Service and Characteristic
[Peripheral] [INF] Start Advetising
[Peripheral] [INF] Advertise Succeeded!

##その他
動作させている室内には、このペリフェラル以外にもBluetoothの電波が多数飛んでいます。
もし、不特定多数の電波が多すぎることが原因なら、
そういった環境下でもコネクトが行える方法があればご教授いただけると幸いです。

##使っているツールのバージョンなど補足情報
Swift 5.0
Xcode 11.0
iOS 12.3
MacOS Mojave 10.14.6

都合上、アップデートができません。
ご助力いただけますと幸いです。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています