Using CBPeripheralManager while using AccessorySetupKit framework

I am working on an app that requires the usage of CoreBluetooth – using both its CBPeripheralManager and CBCentralManager classes. Our app works with other phones and hardware peripherals to exchange data – so we wanted to explore adding AccessorySetupKit to streamline the hardware connection process.

AccessorySetupKit has been integrated (while CBPeripheralManager is turned off) and works great, but even with ASK added to our app's plist file and not in use, CBPeripheralManager fails with error: Cannot create a CBPeripheralManager while using AccessorySetupKit framework.

Is there any workaround or suggested path forward here? We'd still really like to use ASK while keeping our existing functionality, but are not seeing a clear way to do so.

The "while using AccessorySetupKit" state is triggered by the declaration of ASK by adding it to the Info.plist and does not wait for it to be actively used.

Unfortunately it is not possible to use CBPeripheralManager (rather, to acquire the authorization when you do so) if the app has opted in to use ASK.

I've been pulling my hair out, even after pulling everything out in to a on a simple Multi-platform project, with two demos. ASK and Not ASK. If ASK isn't completely branched it burns BT radios.

In the flagship sample project

private static let pinkDice: ASPickerDisplayItem = {
        let descriptor = ASDiscoveryDescriptor()
        descriptor.bluetoothServiceUUID = DiceColor.pink.serviceUUID

        return ASPickerDisplayItem(
            name: DiceColor.pink.displayName,
            productImage: UIImage(named: DiceColor.pink.diceName)!,
            descriptor: descriptor
        )
    }()

I only see bluetoothServiceUUID provided, in the docs however:

Each display item’s descriptor, a property of type ASDiscoveryDescriptor, needs to have a bluetoothCompanyIdentifier or bluetoothServiceUUID, and at least one of the following accessory identifiers: bluetoothNameSubstring A bluetoothManufacturerDataBlob and bluetoothManufacturerDataMask set to the same length. A bluetoothServiceDataBlob and > bluetoothServiceDataMask set to the same length.

It wasn't until I removed bluetoothNameSubstring and ignored documentation, did I get the picker to do something. No clue why or how to debug.

The Service UUIDs given to me are downcased, and that's what I entered in my NSAccessorySetupBluetoothServices array, it crashed because it must running an exact match withCBUUID(string: "my-downcased-uuid").uuidString

let uuid = UUID()
let uuidStringDowncased = uuid.uuidString.lowercased()
let uuidString = uuid.uuidString

let udidFromDownCase = UUID(uuidString: uuidString)
let uuidFromString = UUID(uuidString: uuidStringDowncased)

let cbuuidFromDownCase = CBUUID(string: uuidStringDowncased)
let cbuuidFromString = CBUUID(string: uuidString)

let result = udidFromDownCase == uuidFromString ? "They are the same" : "They are different"
// => They are the same
let result2 = cbuuidFromDownCase == cbuuidFromString ? "They are the same" : "They are different"
// => They are the same

If CBUUID thinks they are the same, shouldn't ASK too, when parsing undocumented plist keys?

For a Project -> New -> Multi-platform App (So MacOS target must init CBCentralManager with privacy plist keys. What keys do I include, and what are the consequences? What breaks what depending on what's included?

NSAccessorySetupBluetoothNames NSAccessorySetupKitSupports NSAccessorySetupBluetoothServices NSBluetoothAlwaysUsageDescription

Within the same binary of an iOS 18 target, how do you demonstrate both implementations, with two separate peripherals? Dice one with ASK, dice two without.

The overload for this signature...whyyyyyyy session.showPicker()

Present a picker that shows accessories managed by a Device Discovery Extension in your app.

session.showPicker(for:)

Present a picker that shows discovered accessories matching an array of display items.

invalidate() sounds important, demo/docs should talk about it more.

Using CBPeripheralManager while using AccessorySetupKit framework
 
 
Q