In the last article we talked about iOS development using the GameKit framework to transfer data between iOS devices on the same network. But the GameKit framework has become obsolete since iOS7, so this article introduces CoreBluetooth, another framework for bluetooth.

Introduction to the

  • CoreBlueTooth. To use CoreBlueTooth for the framework, devices must support Bluetooth 4.0(also known as BLE). , and the phone model must be iPhone4 or higher, that is, at least 4s phone. Development using CoreBluetooth enables data interaction with third-party devices.

Above is the header file for CoreBluetooth, in which the two most Central things are Central and Peripheral.

The object model in CoreBluetooth

  • CBCentralManager is used to manage discover or remotely connect peripheral objects, including scanning, discover, and connect peripherals to ads.

  • CBPeripheralManager It is used to manage the common property profile database of services that publish peripherals locally and the central device (CBCentral object) that notifies these services.

  • CBPeripheral this represents the remote peripheral, an instance of your application’s CBCentralManager — discover ads or the current connection.

  • CBCentral represents a remote central device that connects to an application to perform peripheral functions on the local device.

  • CBService and CBMutableService represent peripheral business data collection, related behavior of a device (or part of a device) that performs a function or feature. The CBMutableService class inherits all attributes of the CBService class that add write access.

  • CBCharacteristic and its subclass, CBMutableCharacteristic, represent further peripheral information services. CBMutableCharacteristic object represents when the feature surrounding the service

  • CBUUID Instances of it represent 128-bit global Unique Identifier (UUID) properties used in Bluetooth low energy communication, such as surrounding services, features, and feature descriptors

  • CBATTRequest which represents the Property Protocol (ATT) read and write request from the remote central device (CBCentral object)

To realize the communication

Central management design pattern

  • First

Import the CoreBluetooth header file, create the central manager properties and peripheral properties, and follow the protocols for the central manager and peripherals.

  • Creating a central controller Lazy load creates a central controller, setting the Peripheral Manager to run in the main thread while creating the proxy as the current controller. If you want to do more complex things with different threads, you create a queue and put it here
- (CBCentralManager *)getCManager{
    if(! _cManager) { _cManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue() options:nil]; }return _cManager;
}
Copy the code
  • Update state (this agent method is triggered whenever the central manager initializes) the state of the central manager

  • Scanning peripherals

// This method is used to tell Central Manager to start looking for a specific service. Not in the center of the state not ON the circumstances of our managers, scanForPeripheralsWithServices method sercices null will scan all of the devices.... (void)centralManagerDidUpdateState:(CBCentralManager *)central{ switch (central.state) {case CBCentralManagerStateUnknown:
            NSLog(@"Central manager status unknown");
            break;
        case CBCentralManagerStateResetting:
            NSLog(@"Central Manager state reset");
            break;
        case CBCentralManagerStateUnsupported:
            NSLog(@"Central manager status not supported");
            break;
        case CBCentralManagerStateUnauthorized:
            NSLog(@"Central manager status is not authorized");
            break;
        case CBCentralManagerStatePoweredOff:
            NSLog(@"Central manager state power off");
            break;
        case CBCentralManagerStatePoweredOn:
        {
            NSLog(@"Central manager state power on"); / / in center managers began to search after successful open peripheral [self. The cManager scanForPeripheralsWithServices: nil options: nil]; // - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI; // find the peripheral}break;
        default:
            break; }}Copy the code
  • If a device is found, the proxy calls this method to filter the peripherals
/* * @param Central The central manager provides this update * @param Peripheral a peripheral object * @param advertisementData a dictionary containing any broadcast and scan response data. * @param RSSI RSSI (Received Signal Strength Indicator) * */ - (void)centralManager (CBCentralManager *) Central  didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{if ([peripheral.name hasPrefix:@"XXX"] && (ABS(RSSI.integerValue) > 35)) {
        // 标记我们的外设,延长他的生命周期
        self.peripheral = peripheral;
        // 进行连接
        [self.cManager connectPeripheral:self.peripheral options:nil];
    }

}
Copy the code
  • Connection status (successful, failed, disconnected) The central manager successfully connects to peripherals. After the connection is successful, services and features can be discovered
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    NSLog(@"%@ connection successful",peripheral.name); Self.peripheral. Delegate = self; self.peripheral. Delegate = self; // peripheral discovery service, passing nil means no filtering // here the peripheral proxy method is triggered - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error [self.peripheral discoverServices:nil]; } / / peripherals connection fails - (void) centralManager: (CBCentralManager *) central didFailToConnectPeripheral: (peripheral CBPeripheral *) error:(NSError *)error { NSLog(@"%@ connection failed",peripheral.name); } // missing connection - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error { NSLog(@"%@ disconnected",peripheral.name);
}
Copy the code
  • Discover service and internal characteristics
// the method called after discovering the peripheral's service - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)errorif (error) {
        NSLog(@"error:%@",error.localizedDescription);
        return;
    }
    for (CBService *service in peripheral.services) {
        [peripheral discoverCharacteristics:nil forService:service]; }} / / discovery service, let equipment found services - (void) the characteristics of internal peripheral (CBPeripheral *) peripheral didDiscoverCharacteristicsForService: (CBService *)service error:(NSError *)error {// traversal featuresfor (CBCharacteristic *characteristic inService. Characteristics) {/ / access features the corresponding description [peripheral discoverDescriptorsForCharacteristic: characteristic]; // Get the value of the feature [peripheralreadValueForCharacteristic:characteristic]; }}Copy the code
  • Update feature
/ / update the description of the characteristics of the value of time is called - (void) peripheral (CBPeripheral *) peripheral didUpdateValueForDescriptor descriptor (CBDescriptor *) error:(NSError *)error { [peripheralreadValueForDescriptor:descriptor]; } / / update feature will be called when the value of - (void) peripheral (CBPeripheral *) peripheral didUpdateValueForCharacteristic: (CBCharacteristic *)characteristic error:(NSError *)error {for (CBDescriptor *descriptor in characteristic.descriptors) {
        [peripheral readValueForDescriptor:descriptor]; }}Copy the code
  • *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

- (void)peripheral:(CBPeripheral *)peripheral didWriteData:(NSData *)data forCharacteristic:(nonnull CBCharacteristic *)characteristic
{
    
    // 
    if(characteristic. The properties & CBCharacteristicPropertyWrite) {/ / the meaning of parameters in the following methods is in turn: write the data to which features Through this response to record the success of write [peripheral writeValue:dataforCharacteristic:characteristic type:CBCharacteristicWriteWithResponse]; }}Copy the code
  • Subscription and unsubscription of notifications generally these two methods are based on product requirements where do they go
- (void)peripheral:(CBPeripheral *)peripheral regNotifyWithCharacteristic:(nonnull CBCharacteristic *)characteristic { // Peripheral is a feature subscription notificationsetNotifyValue:YES forCharacteristic:characteristic]; } - (void)peripheral:(CBPeripheral *)peripheral CancleRegNotifyWithCharacteristic:(nonnull CBCharacteristic * // Cancel the subscription notificationsetNotifyValue:NO forCharacteristic:characteristic];
}
Copy the code
  • disconnect
- (void) dismissConentedWithPeripheral: (peripheral CBPeripheral *) {/ / stop scanning [self. The cManager stopScan]; / / disconnected [self cManager cancelPeripheralConnection: peripheral]; }Copy the code

END

The peripheral management design pattern, which is similar to the central management design pattern, I won’t go into details here, is to follow the peripheral manager protocol and the central protocol, to set up agents, to follow the methods. Code address :github.com/coderqiao/C… .