IOS Bluetooth Programming
Bluetooth programming recently, the company has a new Bluetooth ticket machine, which needs to be programmed. So I read the official documentation for iOS Bluetooth programming. Yesterday the test was successful and I want to write down the snacks, for later viewing.
Let's get down to the truth. The iOS Bluetooth framework supports the Bluetooth 4.0 protocol.
Understand the two important concepts of iOS CoreBluetooth: Central and Periperal Devices
These two concepts can be understood in the traditional mode client-server. central means center, which is similar to server. periperal is a peripheral and generally carries data. We need to obtain data from it, this is an example on the Apple official website. peripheral is a heartbeat meter. It works on schedule. If we go to this peripherals to retrieve heartbeat data, the heartbeat meter works like server, our mobile phone obtains data from the heartbeat device, similar to the client.
How does Peripheral let central know its existence? Peripheral. For example, the heartbeat meter constantly broadcasts its own existence and carries advertising packet during the broadcast process. I don't know if the translation is correct. If not, please correct me. As if a device is shouting, Here ~ I am a heartbeat instrument, and I am a heartbeat instrument. This is my service (advertising package ). Central finds a device shouting, and says, "Let's see if you need to provide services. Let's take a look at it ". In this way, you can discover the device and obtain the services it provides. Export/y747Goy/zm4bmp tcs3/release + OxqMv509C3/release + zvG9 + release/HIobXEt/release + release/release + NDQtsHQtLLZ1/ejrNXiwO + 78cihstnX96Osvs3Kx7bBstnX96Gju/HIobW9ttTTpsr9vt3UtM23Cjxicj4KCr + 133 "http://www.2cto.com/uploadfile/Collfiles/20141201/2014120109200053.png" alt = "\">
After introducing these concepts, let's take a look at how to fill in the actual code. this is written for my Bluetooth ticket machine. Because I want to write to the Bluetooth ticket machine, the mobile phone searches for peripharal, so the mobile phone is central, and the invoice machine is peripharal1. first import This framework 2. There are several main classes of this framework worth noting. CBCentralManager, the Central we mentioned earlier, can be used to discover peripherals.
#import
@interface ViewController ()
@property (nonatomic, retain) CBCentralManager *centralManager;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];}
The above Code creates a CBCentralManager to detect peripherals. When the creation is successful, CBCentralManager calls back the proxy to say that the creation is successful, as shown in the following code:
/* Invoked whenever the central manager's state is updated. */- (void)centralManagerDidUpdateState:(CBCentralManager *)central{ NSString * state = nil; switch ([central state]) { case CBCentralManagerStateUnsupported: state = @"The platform/hardware doesn't support Bluetooth Low Energy."; break; case CBCentralManagerStateUnauthorized: state = @"The app is not authorized to use Bluetooth Low Energy."; break; case CBCentralManagerStatePoweredOff: state = @"Bluetooth is currently powered off."; break; case CBCentralManagerStatePoweredOn: state = @"work"; break; case CBCentralManagerStateUnknown: default: ; } NSLog(@"Central manager state: %@", state);}
If the above Code is CBCentralManagerStatePoweredOn at this time, it indicates Bluetooth is available. You must enable scanning peripherals after callback of this method; otherwise, no response is made.
3. Now you can connect to and scan peripherals.
- (IBAction)scan:(id)sender { [self.centralManager scanForPeripheralsWithServices:nil options:nil];}
In the above code, I created a button to scan, so the corresponding xib image is not displayed.
If this method is passed in nil, it means scanning all peripherals.
- (IBAction)scan:(id)sender { [self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@"FFE0"]] options:nil];}
If you only want to search for peripherals that provide the corresponding Service number (go to the advertising packet of peripharal to match the Service number, and input an array, the object is CBUUID, which is the unique identifier of the Service. Generally, if we search for an nil, we will know what the desired service looks like. Then we can use this known service directly by programming. Unless the manufacturer of your Bluetooth device changes the service number, it is almost impossible.
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{ static int i = 0; NSString *str = [NSString stringWithFormat:@"Did discover peripheral. peripheral: %@ rssi: %@, UUID: %@ advertisementData: %@ ", peripheral, RSSI, peripheral.UUID, advertisementData]; NSLog(@"%@",str); [self.discoverdPeriparals addObject:peripheral];}
When you find a device, this method calls back. Peripheral indicates the device you have discovered, AD data for advertisementData, and received signal strength.
You can see a service UUIDs from broadcast data, because the number of broadcast data is limited, the data is relatively small. However, we only found this device. If it is already a device we are interested in, you can stop scanning through [self. centralManager stopScan] or continue scanning.
4. Connect discovered peripherals
- (IBAction)connect:(id)sender { [self.centralManager connectPeripheral:[self.discoverdPeriparals firstObject] options:nil];}
Suppose the first one is the peripherals we need to connect to it.
/* Invoked whenever a connection is succesfully created with the peripheral. Discover available services on the peripheral */- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{ NSLog(@"Did connect to peripheral: %@", peripheral); peripheral.delegate = self; [central stopScan]; [peripheral discoverServices:nil];}
Call this method after the connection is successful. In this case, we set the proxy for the peripheral so that peripheral can return all services to us.
[peripheral discoverServices:@[[CBUUID UUIDWithString:@"FFE0"]]];
This method is also passed in nil to return all services. If it is passed in a specific service id, only the service is returned. Here we pass in nil to return all services.
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{ if (error) { NSLog(@"Discovered services for %@ with error: %@", peripheral.name, [error localizedDescription]); return; } for (CBService *service in peripheral.services) { NSLog(@"Service found with UUID: %@", service.UUID); if ([service.UUID isEqual:[CBUUID UUIDWithString:@"FFE0"]]) { [peripheral discoverCharacteristics:nil forService:service]; } }}
Here we can see that two services are returned, because FFE0 is required, so let the service return the corresponding characteristics.
[peripheral discoverCharacteristics:nil forService:service];
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{ if (error) { NSLog(@"Discovered characteristics for %@ with error: %@", service.UUID, [error localizedDescription]); return; } for (CBCharacteristic * characteristic in service.characteristics) { DLog(@"%@",characteristic); if( [characteristic.UUID isEqual:[CBUUID UUIDWithString:@"FFE1"]]) { self.p = peripheral; self.c = characteristic; //read //[testPeripheral readValueForCharacteristic:characteristic]; NSLog(@"Found a Device Manufacturer Name Characteristic - Read manufacturer name"); } }}
The above method is to find all the features of FEE0 service. There is only one feature here, that is, the write feature of FFE0 write service on the Bluetooth ticket machine. This feature is obtained. Write service, the specific log will not be written
-(Void) touchesBegan :( NSSet *) touches withEvent :( UIEvent *) event {NSString * RStr = @ "2764"; NSMutableString * str = [NSMutableString new]; [str appendFormat: @ "% c", 28]; [str appendFormat: @ "% c", 33]; [str appendFormat: @ "% c", 8]; [self. p writeValue: [str dataUsingEncoding: CFStringConvertEncodingToNSStringEncoding (kCFStringEncodingGB_18030_2000)] forCharacteristic: self. c type: CBCharacteristicWriteWithRe Else se]; RStr = @ "Hello, Wu shuifeng !!! \ N "; [self. p writeValue: [RStr dataUsingEncoding: CFStringConvertEncodingToNSStringEncoding (kCFStringEncodingGB_18030_2000)] forCharacteristic: self. c type: CBCharacteristicWriteWithResponse];}
Here, I write the features provided by the Bluetooth Ticket Server. Successful.
Supplement:
If the feature is readable, you can subscribe to the feature.
[Peripheral setpolicyvalue: YES forCharacteristic: interestingCharacteristic];
This method calls back peripheral: didUpdateValueForCharacteristic: error: Method
If the data is updated after the subscription is successful, this method is called back. You can read the data you want.
For more information, see CoreBluetooth programming guid provided in the official iOS documentation.