为什么我的CBPeripheralManager广告不可发现?

问题描述:

我正在制作核心蓝牙应用程序,使用我的iPhone作为外设,并将我的Mac作为*处理器。我的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") 
    } 
} 
} 

它打印出蓝牙状态打开和广告。在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代码 –

我首选的扫描外设的方法是不明确地要求任何服务。我发现,当CBCentralManager有时无法从广告本身指示服务时,该路线导致头痛。

相反,你感兴趣的是了解周边的更可靠的方法是在你的scanForPeripheral参数未指定任何服务和扫描一切,只有一次。在您的options字典中包含CBCentralManagerScanOptionAllowDuplicatesKey密钥,其值为false包装在NSNumber中。

而且当您收到didDiscover peripheral:的回拨方法时,请查看advertisingData。它将有一个名为kCBAdvDataServiceUUIDs的字段。这将是您在外设上放置的一系列服务UUID。检查这些(通常只有一个),看看是否有任何符合你感兴趣的服务UUID,如果是的话,那些是你的外围设备。


SCAN

注:通常我做这个固定的时间间隔的基础上。

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

回调

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

这是最好的答案。 –

FYI代码有工作就好了重新启动后,所以很明显,这是与蓝牙核心毛刺。如果其他人有这个问题,一定要试试这个!