Вы получаете сообщение об ошибке, потому что вы вызываете startAdvertising
сразу после создания экземпляра CBPeripheralManager
. Как говорится в сообщении об ошибке, вы должны подождать, пока не получите обратный вызов с указанием состояния CBManagerStatePoweredOn
, прежде чем выполнять какие-либо операции Bluetooth.
На самом деле начинать рекламу в этот момент бессмысленно, потому что вы еще не определили ваш сервис. Вам просто нужно переместить вызов startAdvertising
в метод peripheralManagerDidUpdateState
, в котором вы настраиваете свой сервис:
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
if (peripheral.state == CBManagerStatePoweredOn) {
self.transferCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID] properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable];
CBMutableService *transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID] primary:YES];
transferService.characteristics = @[_transferCharacteristic];
[_peripheralManager addService:transferService];
[_peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]] }];
}
if (peripheral.state != CBManagerStatePoweredOn) {
return;
}
}
Кроме того, из соображений стиля я бы не получил доступ к _peripheralManager
ivar напрямую, если у вас нет веских причин. Всегда лучше использовать сеттер / геттер. Потеря производительности является незначительной, и она позволяет избежать незначительных ошибок в случае, когда установщик / получатель был переопределен.