iOS CoreBluetooth: startAdvertising() Error advertising static data

僤鯓⒐⒋嵵緔 提交于 2019-12-07 04:57:33

问题


I want to advertise static data. I'm using Swift 2.2.1 and CoreBluetooth on iOS. My app builds bluetooth Services and their corresponding Characteristics, then calls startAdvertising(), and the peripheralManagerDidStartAdvertising90 callback returns this error:

peripheralManagerDidStartAdvertising encountered an error. // Mine
One or more parameters were invalid. // ...from Apple CoreBluetooth
nil  // ... return value from Apple CoreBluetooth callback

I'm relatively new to Swift and iOS development so my guess is that I'm doing something goofy, but so far I can't figure out what.

I'll attempt to distill things down for more experienced eyes.

- - - - - - pointutility.swift - - - - - - -
// This is a code excerpt and probably won't compile.

// UUID for the one peripheral service, declared outside the class:
var peripheralServiceUUID = CBUUID(string: "9BC1F0DC-F4CB-4159-BD38-7375CD0DD545")

// UUID for one characteristic of the service above, declared outside the class:
var nameCharacteristicUUID = CBUUID(string: "9BC1F0DC-F4CB-4159-BD38-7B74CD0CD546")

class PointUtility: NSObject, CBPeripheralManagerDelegate {

var peripheralManager:CBPeripheralManager?
var bluetoothServices:CBMutableService?
var nameCharacteristic:CBMutableCharacteristic?

override init() {
    super.init()
    peripheralManager = CBPeripheralManager(delegate:self, queue:nil)
    bluetoothServices = CBMutableService(type: peripheralServiceUUID, primary: true)
}

func configureUtilityForIdentity(identity:Point!) {
    var characteristicsArray:[CBCharacteristic] = []
    myIdentity = identity

      if (identity.name != nil) {
        nameCharacteristic =
            CBMutableCharacteristic(type: nameCharacteristicUUID,
                properties: (CBCharacteristicProperties.Read),
                value: myIdentity?.name?.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false),
                permissions: CBAttributePermissions.Readable)

        characteristicsArray.append(nameCharacteristic!)
      }

    // more characteristics built here and added to the characteristicsArray[]...
    // ... then all are added to the CBMutableService at the bottom...
    bluetoothServices?.characteristics = characteristicsArray as [CBCharacteristic]
}


func peripheralManagerDidUpdateState(peripheral: CBPeripheralManager) {
    switch (peripheral.state) {
    case .PoweredOn:
        print("Current Bluetooth State:  PoweredOn")
        publishServices(bluetoothServices)
        break;
    case .PoweredOff:
        print("Current Bluetooth State:  PoweredOff")
        break;
    case .Resetting:
        print("Current Bluetooth State:  Resetting")
        break;
    case .Unauthorized:
        print("Current Bluetooth State:  Unauthorized")
    case .Unknown:
        print("Current Bluetooth State:  Unknown")
        break;
    case .Unsupported:
        /
        print("Current Bluetooth State:  Unsupported")
        break;
    }
}

func publishServices(newService:CBMutableService!) {
    peripheralManager?.addService(newService)
}

func peripheralManager(peripheral: CBPeripheralManager, didAddService service: CBService, error: NSError?) {

    if (error != nil) {
        print("PerformerUtility.publishServices() returned error: \(error!.localizedDescription)")
        print("Providing the reason for failure: \(error!.localizedFailureReason)")
    }
    else {
        peripheralManager?.startAdvertising([CBAdvertisementDataServiceUUIDsKey : service.UUID])
    }
}

func peripheralManagerDidStartAdvertising(peripheral: CBPeripheralManager,
    error: NSError?) {
        if (error != nil) {
            print("peripheralManagerDidStartAdvertising encountered an error.")
            print(error!.localizedDescription)  // Error: One or more parameters were invalid
            print(error!.localizedFailureReason)  // Error: nil
        }
        print ("Debug: peripheralManagerDidStartAdvertising()")
}
}
- - - - - - pointutility.swift - - - - - - -

I really appreciate any assistance offered.

Best Regards,

Michael


回答1:


The value for the CBAdvertisementDataServiceUUIDsKey in the dictionary passed to startAdvertising is an array of CBUUID objects, but you are only passing a single CBUUID. Once I changed it to an array your code worked.

func peripheralManager(peripheral: CBPeripheralManager, didAddService service: CBService, error: NSError?) {

    if (error != nil) {
        print("PerformerUtility.publishServices() returned error: \(error!.localizedDescription)")
        print("Providing the reason for failure: \(error!.localizedFailureReason)")
    }
    else {
        peripheralManager?.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [service.UUID]])
    }
}



回答2:


a few minor points; I have an additional parameter.

peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil)

I have this code in peripheralManagerDidUpdateState, right @ the top.

if (peripheral.state != .PoweredOn) {
    return;
}

And I call this within the same method, assuming it is powered on of course.

transferCharacteristic = CBMutableCharacteristic(type: cbtransfer, properties: .Notify, value: nil, permissions: .Readable)
transferService = CBMutableService(type: cbservice, primary: true)
transferService.characteristics = [transferCharacteristic]

Finally I do this:

peripheralManager!.addService(transferService)                    
peripheralManager!.startAdvertising([CBAdvertisementDataServiceUUIDsKey :[cbservice]])

But note; I don't append the characteristics; I use the syntax you see here, appending doesn't work. For reasons I don't clearly understand Swift says its ok, but so it is syntactically good, but BLE doesn't like it.

func publishServices(newService:CBMutableService!) {
    peripheralManager?.addService(newService)
}

Review your code and make the changes; it should work.




回答3:


The error parameter in the method:

func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?)

Reports the error:

Error Domain=CBErrorDomain Code=1 "One or more parameters were invalid." UserInfo={NSLocalizedDescription=One or more parameters were invalid.}

Issue was needing to pass an array of UUIDs and also use the CBUUID(string:) type rather than UUID(uuidString:). Each issue reproduces the error independently.

struct BluetoothPeripheral {
    let localName: String
    let uuid: String

    func peripheralData() -> [String : Any] {
        return [
            CBAdvertisementDataLocalNameKey    : localName,
            CBAdvertisementDataServiceUUIDsKey : [CBUUID(string: uuid)],
        ]
    }
}


来源:https://stackoverflow.com/questions/35858183/ios-corebluetooth-startadvertising-error-advertising-static-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!