2017-08-25 5 views
0

私は周辺機器として私のiPhoneを使用し、中心として私のMacを使用してコアのBluetoothのアプリケーションを作っている。私のiPhoneはオンになって広告を出していますが、ブルートゥースブラウザでは他のiPhoneやMacでそれを発見することはできません。しかし、私の友人のAndroidの携帯電話はそれを発見することができます。どうしたの? のiOSエンド:私のCBPeripheralManagerは広告を表示しますが、検出できないのはなぜですか?

import UIKit 
import CoreBluetooth 

class ViewController: UIViewController, CBPeripheralManagerDelegate { 

@IBOutlet weak var statusLabel: UILabel! 
@IBOutlet weak var connectionInfoLabel: UILabel! 
var peripheralManager: CBPeripheralManager! 
var accelerometerXCharacteristic: CBMutableCharacteristic! 
var phoneDataService: CBMutableService! 
var accelerometerXData: Data! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    connectionInfoLabel.isHidden = true 
    //Ignore this I was testing the data encoding 
    let accelerometerVal = "45" 
    let someData = accelerometerVal.data(using: String.Encoding.utf8) 
    let revertedString = String(data: someData!, encoding: String.Encoding.utf8)! as String 
    let integer = Int(revertedString)! 
    print(integer) 

    setupBT(delegate: self, intialXData: someData!) 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

func setupBT(delegate: CBPeripheralManagerDelegate, intialXData: Data) { 
    peripheralManager = CBPeripheralManager(delegate: delegate, queue: nil) 
    //print(peripheralManager.state) 

    let accelerometerXCharacteristicUUID = CBUUID(string: "07B24C73-C35B-45C7-A43D-58240E3DB4DF") 
    let phoneDataServiceUUID = CBUUID(string: "CAB1B028-2243-4F2C-A2F1-3BE5AD51AD61") 

    accelerometerXCharacteristic = CBMutableCharacteristic(type: accelerometerXCharacteristicUUID, properties: CBCharacteristicProperties.read, value: intialXData, permissions: CBAttributePermissions.readable) 

    phoneDataService = CBMutableService(type: phoneDataServiceUUID, primary: true) 
    phoneDataService.characteristics = [accelerometerXCharacteristic] 



} 

func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { 
    var statusMessage = "" 

    switch peripheral.state { 
    case .poweredOn: 
     statusMessage = "Bluetooth Status: Turned On" 
     peripheralManager.add(phoneDataService) 
     peripheralManager.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [phoneDataService.uuid], CBAdvertisementDataLocalNameKey: "DSiPhone"]) 

    case .poweredOff: 
     statusMessage = "Bluetooth Status: Turned Off" 

    case .resetting: 
     statusMessage = "Bluetooth Status: Resetting" 

    case .unauthorized: 
     statusMessage = "Bluetooth Status: Not Authorized" 

    case .unsupported: 
     statusMessage = "Bluetooth Status: Not Supported" 

    default: 
     statusMessage = "Bluetooth Status: Unknown" 
    } 

    print(statusMessage) 

} 

func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) { 
    if ((error) != nil) { 
     print("Error \(error!.localizedDescription)") 
    } 
} 

func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) { 
    print("Advertising") 
    if ((error) != nil) { 
     print("Error advertising \(error!.localizedDescription)") 
    } 
} 

func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) { 
    var requestedCharacteristic: CBMutableCharacteristic? 
    switch request.characteristic.uuid { 
    case accelerometerXCharacteristic.uuid: 
     requestedCharacteristic = accelerometerXCharacteristic 
    default: 
     requestedCharacteristic = nil 

    } 
    if let characteristic = requestedCharacteristic { 
     if request.offset > characteristic.value!.count { 
      request.value = characteristic.value?.subdata(in: request.offset..<(characteristic.value!.count - request.offset)) 
      peripheralManager.respond(to: request, withResult: CBATTError.success) 
     } else { 
      peripheralManager.respond(to: request, withResult: CBATTError.invalidAttributeValueLength) 
     } 
    } else { 
     peripheralManager.respond(to: request, withResult: CBATTError.attributeNotFound) 
    } 
} 

func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) { 
    print("Connection Successful") 
    statusLabel.text = "Successful!" 
    let didSendValue = peripheralManager.updateValue(accelerometerXData, for: characteristic as! CBMutableCharacteristic, onSubscribedCentrals: nil) 
    if !didSendValue { 
     print("Send failed") 
    } 
} 
} 

Bluetoothの状態がオンと広告されていることをプリントアウトしています。 Macの場合:

import Cocoa 
import CoreBluetooth 

class ViewController: NSViewController, CBCentralManagerDelegate { 
var centralManager: CBCentralManager! 
override func viewDidLoad() { 
    super.viewDidLoad() 
    centralManager = CBCentralManager(delegate: self, queue: nil) 

    // Do any additional setup after loading the view. 
} 

override var representedObject: Any? { 
    didSet { 
    // Update the view, if already loaded. 
    } 
} 

func setupBT() { 

} 

func centralManagerDidUpdateState(_ central: CBCentralManager) { 
    var statusMessage = "" 
    switch central.state { 
    case .poweredOn: 
     centralManager.scanForPeripherals(withServices: [CBUUID(string: "CAB1B028-2243-4F2C-A2F1-3BE5AD51AD61")], options: nil) 
     statusMessage = "Bluetooth Status: Turned On" 

    case .poweredOff: 
     statusMessage = "Bluetooth Status: Turned Off" 

    case .resetting: 
     statusMessage = "Bluetooth Status: Resetting" 

    case .unauthorized: 
     statusMessage = "Bluetooth Status: Not Authorized" 

    case .unsupported: 
     statusMessage = "Bluetooth Status: Not Supported" 

    default: 
     statusMessage = "Bluetooth Status: Unknown" 
    } 

    print(statusMessage) 
} 

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { 
    print("Discovered") 
} 
} 

電源が入っていても何も発見されていません。

+0

周辺機器をどのように見つけようとしていますか? –

+0

設定でブルートゥースデバイスブラウザを使用してもそれを検出できず、どちらも私のMacコアのブルートゥースアプリケーションではありませんでした。必要に応じてMacコードを提供することができます –

+0

@BrandonA Macコードを追加しました –

答えて

1

私がペリフェラルをスキャンするのに好ましい方法は、特にサービスを特に要求しないことです。 CBCentralManagerが広告自体からサービスを示すことができないときに、そのルートが頭痛につながることがわかりました。

scanForPeripheralパラメータにサービスを指定せず、すべての情報をにスキャンすると、興味のある周辺機器をより確実に検出できます。 options辞書にはfalseの値を持つCBCentralManagerScanOptionAllowDuplicatesKeyキーが含まれており、NSNumberにラップされています。

didDiscover peripheral:メソッドからコールバックを受け取ったら、advertisingDataを調べてください。フィールドにはkCBAdvDataServiceUUIDsというフィールドがあります。これは、周辺機器に配置した一連のサービスUUIDになります。これら(通常はただ1つ)をチェックし、あなたが興味のあるサービスUUIDに一致するかどうかを確認します。もしそうなら、それはあなたの周辺機器です。


SCAN

注:一般的に、私はタイミング間隔毎にこれを行います。

let options: [String: Any] = [CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(value: false)] 
centralManager?.scanForPeripherals(withServices: nil, options: options) 

CALLBACK

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { 
    if let ids = advertisementData["kCBAdvDataServiceUUIDs"] as? [CBUUID], 
    let id = ids.first, 
    id == CBUUID(string: "YourServiceID") { 
     print("Found Peripheral \(peripheral)") 
    } 
} 
+0

これは最高の答えです。 –

0

FYIがそのコードは、再起動後にうまく働いていたので、明らかにこれはコアBluetooth搭載グリッチでした。誰かがこの問題を抱えているなら、間違いなくこれを試してみてください!

関連する問題