Ios Obj-c:核心蓝牙-API误用:<;CBPeripheralManager:0x28382c6e0>;只能在通电状态下接受此命令?
我正在设置外围设备及其视图控制器以发送蓝牙数据-由于某些原因,当我运行我的应用程序时,我收到以下错误: [CoreBluetooth]API误用:can 仅在通电状态下接受此命令 不知道为什么会发生这种情况。蓝牙已打开,我的代码似乎顺序正确 ViewController.mIos Obj-c:核心蓝牙-API误用:<;CBPeripheralManager:0x28382c6e0>;只能在通电状态下接受此命令?,ios,objective-c,core-bluetooth,Ios,Objective C,Core Bluetooth,我正在设置外围设备及其视图控制器以发送蓝牙数据-由于某些原因,当我运行我的应用程序时,我收到以下错误: [CoreBluetooth]API误用:can 仅在通电状态下接受此命令 不知道为什么会发生这种情况。蓝牙已打开,我的代码似乎顺序正确 ViewController.m - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
[_peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]] }];
}
- (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];
}
if (peripheral.state != CBManagerStatePoweredOn) {
return;
}
}
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic {
_dataToSend = [_textView.text dataUsingEncoding:NSUTF8StringEncoding];
_sendDataIndex = 0;
[self sendData];
}
- (void)sendData {
static BOOL sendingEOM = NO;
// end of message?
if (sendingEOM) {
BOOL didSend = [self.peripheralManager updateValue:[@"EOM" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil];
if (didSend) {
// It did, so mark it as sent
sendingEOM = NO;
}
// didn't send, so we'll exit and wait for peripheralManagerIsReadyToUpdateSubscribers to call sendData again
return;
}
// We're sending data
// Is there any left to send?
if (self.sendDataIndex >= self.dataToSend.length) {
// No data left. Do nothing
return;
}
// There's data left, so send until the callback fails, or we're done.
BOOL didSend = YES;
while (didSend) {
// Work out how big it should be
NSInteger amountToSend = self.dataToSend.length - self.sendDataIndex;
// Can't be longer than 20 bytes
if (amountToSend > NOTIFY_MTU) amountToSend = NOTIFY_MTU;
// Copy out the data we want
NSData *chunk = [NSData dataWithBytes:self.dataToSend.bytes+self.sendDataIndex length:amountToSend];
didSend = [self.peripheralManager updateValue:chunk forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil];
// If it didn't work, drop out and wait for the callback
if (!didSend) {
return;
}
NSString *stringFromData = [[NSString alloc] initWithData:chunk encoding:NSUTF8StringEncoding];
NSLog(@"Sent: %@", stringFromData);
// It did send, so update our index
self.sendDataIndex += amountToSend;
// Was it the last one?
if (self.sendDataIndex >= self.dataToSend.length) {
// Set this so if the send fails, we'll send it next time
sendingEOM = YES;
BOOL eomSent = [self.peripheralManager updateValue:[@"EOM" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil];
if (eomSent) {
// It sent, we're all done
sendingEOM = NO;
NSLog(@"Sent: EOM");
}
return;
}
}
}
- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral {
[self sendData];
}
出现此错误是因为在实例化
cbperipheraldmanager
实例后,您立即调用了startAdvertising
。正如错误所述,在执行任何蓝牙操作之前,必须等待收到带有CBManagerStatePoweredOn
状态指示的回调
事实上,从那时开始做广告是没有意义的,因为你还没有定义你的服务。您只需将startAdvertising
调用移动到peripherandmanagerdidupdatestate
方法中即可设置服务:
- (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;
}
}
另外,作为一种风格,除非你有充分的理由,否则我不会直接访问\u peripheraldmanager
ivar。最好使用setter/getter。性能损失很小,在setter/getter被重写的情况下,它避免了细微的错误