第一步,建立一个Peripheral Manager,进行分配和初初始化,通过CBPeriphralManager类方法initWithDelegate:queue:options
myPeripheralManager = |
[[CBPeripheralManager alloc] initWithDelegate:self queue:nil options:nil]; |
CBUUID *heartRateServiceUUID = [CBUUID UUIDWithString: @"180D"];
当你建立了一个预定义16-bitUUID的CBUUID对象时,Core Bluetooth会基于Bluetooth 基础 UUID 来预先填充上128-bitUUID剩余的部分。
$ uuidgen |
71DA3FD1-7E10-41C1-B16F-4430B506CDE7 |
CBUUID *myCustomServiceUUID = |
[CBUUID UUIDWithString:@"71DA3FD1-7E10-41C1-B16F-4430B506CDE7"]; |
myCharacteristic = |
[[CBMutableCharacteristic alloc] initWithType:myCharacteristicUUID |
properties:CBCharacteristicPropertyRead |
value:myValue permissions:CBAttributePermissionsReadable]; |
有了一个可变的characteristic,同时建立一个可变的services
myService = [[CBMutableService alloc] initWithType:myServiceUUID primary:YES];
primary:YES表明是主要的service,这是相对于secondary的service而言的。建立service和characteristic的联系:
myService.characteristics = @[myCharacteristic];
第三步,出版(publish)services和characteristics
使用CBPeripheralManager类方法addService:
[myPeripheralManager addService:myService];
peripheral manager采用peripheralManager:didAddService:error方法来处理services不能被出版的情况,如下
- (void)peripheralManager:(CBPeripheralManager *)peripheral |
didAddService:(CBService *)service |
error:(NSError *)error { |
|
if (error) { |
NSLog(@"Error publishing service: %@", [error localizedDescription]); |
} |
... |
第四步,广播(advertising)services
使用CBPeripheralManager类方法startAdvertising:
[myPeripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : |
@[myFirstService.UUID, mySecondService.UUID] }]; |
- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral |
error:(NSError *)error { |
|
if (error) { |
NSLog(@"Error advertising: %@", [error localizedDescription]); |
} |
... |
一旦开始广播数据,附近的centrals就可以发现和初识化连接了。
第五步,来自central的读写命令反馈
但连接的central要求(request)去读一个characteristic的值的时候,peripheral manager就会调用方法peripheralManager:didReceiveReadRequest
- (void)peripheralManager:(CBPeripheralManager *)peripheral |
didReceiveReadRequest:(CBATTRequest *)request { |
|
if ([request.characteristic.UUID isEqual:myCharacteristic.UUID]) { |
... |
if (request.offset > myCharacteristic.value.length) { |
[myPeripheralManager respondToRequest:request |
withResult:CBATTErrorInvalidOffset]; |
return; |
} |
request.value = [myCharacteristic.value |
subdataWithRange:NSMakeRange(request.offset, |
myCharacteristic.value.length - request.offset)]; |
[myPeripheralManager respondToRequest:request withResult:CBATTErrorSuccess]; |
... |
写命令类似的,可以写characteristic的值:
myCharacteristic.value = request.value;
在写值要确保把offset考虑进去。
每调用peripheralManager:didReceiveWriteRequest:方法,就要调用一次respondToRequest:withResult:方法
[myPeripheralManager respondToRequest:[requests objectAtIndex:0] |
withResult:CBATTErrorSuccess]; |
- (void)peripheralManager:(CBPeripheralManager *)peripheral |
central:(CBCentral *)central |
didSubscribeToCharacteristic:(CBCharacteristic *)characteristic { |
|
NSLog(@"Central subscribed to characteristic %@", characteristic); |
... |
使用上面的代理方法,表明要开始发送central更新值
接着,得到characteristic更新值,发送到central,调用CBPeripheralManager类方法updateValue:forCharacteristic:onSubscribedCentrals:
NSData *updatedValue = // fetch the characteristic's new value |
BOOL didSendValue = [myPeripheralManager updateValue:updatedValue |
forCharacteristic:characteristic onSubscribedCentrals:nil]; |
通过方法updateValue:forCharacteristic:onSubscribedCentrals:返回一个布尔量表明更新值是否送到已订阅的central了。
如果用来发送更新值的基础队列是满的,则返回NO。当有更多的空间可用发送队别时,调用peripheralManagerIsReadyToUpdateSubscribes:
再次调用方法updateValue:forCharacteristic:onSubscribedCentrals:就可以重发值了。
注意:依据characteristic值的大小,并不是所有的值是通过notifications传输的。可以通过CBPeriphral类方法readDataForCharacteristic:来得到完整的值