I'm trying to explore accessory setup kit and migrate an existing CoreBluetooth-paired BLE device into AccessorySetupKit using ASMigrationDisplayItem. The regular ASPickerDisplayItem discovery picker works perfectly on the same device/session/Info.plist. But ASMigrationDisplayItem consistently fails.
Code
let descriptor = ASDiscoveryDescriptor()
descriptor.bluetoothServiceUUID = CBUUID(string: "0xFDEE")
let migrationItem = ASMigrationDisplayItem(
name: "HUAWEI FreeClip 2",
productImage: productImage,
descriptor: descriptor
)
migrationItem.peripheralIdentifier = peripheralIdentifier
// peripheralIdentifier is a valid CBPeripheral.identifier UUID
// CBCentralManager is suspended before this call (suspendForASK)
session?.showPicker(for: [migrationItem]) { error in
// Completion is either called with error 500, or NEVER called (silent no-op)
}
Test Results (8 rounds)
| 1 | suspendForASK → immediate showPicker | Silent no-op |
| 2 | suspendForASK → 0.6s delay → showPicker | Silent no-op |
| 3 | .activated event → showPicker (no CBManager exists yet) | Silent no-op |
| 4 | viewDidAppear → 0.5s delay → showPicker | Silent no-op |
| 5 | User taps alert button (explicit gesture context) → showPicker | Silent no-op |
| 6 | Clear pickerDisplaySettings before migration showPicker | Error 500 (pickerAlreadyActive) |
| 7 | invalidate() → activate() → immediate showPicker (fresh session) | Silent no-op |
| 8 | invalidate() → activate() → wait for .activated → showPicker | Silent no-op |
Round 6 logs (Error 500):
[ASK] Starting migration for peripheral: D0F13212-****
Picker already activated ← System message
[ASK] Migration picker failed: ASErrorDomain error 500.
Round 8 logs (Silent no-op, cleanest test):
XPC connection invalid ← System message
[ASK] Session invalidated: no error
[ASK] Session activated ← New session .activated
[ASK] Executing pending migration showPicker after .activated
// → NO pickerDidPresent, NO migrationComplete, NO completion callback, NO error, NO UI
Ruled Out
- Info.plist — regular
ASPickerDisplayItemworks with identical config - Session state —
.activatedconfirmed, session non-nil - CBManager conflict — suspended before migration; round 3 ran before any CBManager existed
- User gesture — round 5 inside button tap handler (same context as working picker)
- Timing — delayed to
viewDidAppear, waited for.activatedevent - peripheralIdentifier — valid UUID, device is actively connected via CoreBluetooth
Questions
-
Is
ASMigrationDisplayItemfully functional on iOS 26.x? Across 8 different invocation patterns, it either returns error 500 or silently no-ops — no UI ever appears. -
What causes the residual "Picker already activated" state (error 500), and how do we properly reset it?
-
The
XPC connection invalidsystem message appears consistently. Does this indicate the daemon is rejecting the migration request? -
Are there prerequisites we're missing? E.g., must the device be disconnected from CB? Must
NSBluetoothAlwaysUsageDescriptionbe removed? Is there a different descriptor requirement for migration vs discovery?