9 Replies
      Latest reply on Oct 30, 2015 9:30 AM by Gualtier Malde
      omsignal Level 1 Level 1 (0 points)

        Hi,

         

        I just installed the new IOS9 Beta 5 version on my iPod (5th generation) and I am now trying to use my BLE application.

         

        Scenario is:

        I am able to connect successfully to the other little BLE device then I want to write on an encrypted characteristic. Right after the write command, I have the regular IOS pairing popup then after I entered the correct pairing key I am not receiving any confirmation through 'didWriteValueForCharacteristic' delegate method.

         

        Notes:

        This scenario is working fine with IOS8.

        This scenario is working fine if I simulate the little BLE device on an IOS device. (I also noticed that pairing procedure between 2 IOS devices was different)

         

        Do you guys know if IOS9 pairing procedure has been changed ? Is there a new protocol to follow ?

         

        Thank you !

        • Re: Pairing issues with IOS9 Beta 5
          omsignal Level 1 Level 1 (0 points)

          What is the current BLE specification implemented in IOS 9 ?

          • Re: Pairing issues with IOS9 Beta 5
            pshk Level 1 Level 1 (0 points)

            We are having similar issue with our BLE pairing. I hope Apple engineers are looking at this issue and fix it in GM build or release another beta.

            • Re: Pairing issues with IOS9 Beta 5
              Gualtier Malde Apple Staff Apple Staff (530 points)

              Everyone, we need as much detailed information about the BLE device exhibiting the issue.

              Make, model, firmware version. If you know the details about the BLE module/controller, please post as much information as you can about that as well.

              Post them here so others can compare the info with their devices.

              Also file a Radar at https://bugreport.apple.com with the same information as soon as possible.


                • Re: Pairing issues with IOS9 Beta 5
                  sborza Level 1 Level 1 (0 points)

                  We have this problem with iPhone 6 running iOS 9 connecting to a Ti CC2540 BLE dongle powered device.

                  This device have worked fine pairing to all phones from 4S to 6...

                    • Re: Pairing issues with IOS9 Beta 5
                      lc_fafnir Level 1 Level 1 (0 points)

                      Our setup for this error is:

                       

                      - the device BLE controller is a nordic N51822

                      - tested with iPhone A1429 (but fails also on all other iPhones with BLE4.x capabilities)

                      - iOS Build is 9.1 (13B143) (but also fails with all iOS version from 9.x up, even all the betas)

                       

                      So what I've done is:

                       

                      In code i use some constants for convenience:

                       

                      #define findMeServiceUUID            [CBUUID UUIDWithString:@"1802"]
                      #define genericAccessServiceUUID      [CBUUID UUIDWithString:@"1800"]
                      #define linkLossServiceUUID          [CBUUID UUIDWithString:@"1803"]
                      #define deviceNameCharacteristicUUID  [CBUUID UUIDWithString:@"2A00"]
                      #define alertLevelCharacteristicUUID  [CBUUID UUIDWithString:@"2A06"]
                      #define BT_ALERT_LEVEL_NONE 0
                      #define BT_LEVEL_MILD 1
                      #define BT_ALERT_LEVEL_HIGH 2
                      #define BT_ALERT_LEVEL_RESERVED(LVL) LVL
                      

                       

                      1. Scan for peripherals with findMe and linkLoss Service (1802 and 1803):

                       

                        NSDictionary* scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
                                                                                forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
                        NSArray* serviceArray = [NSArray arrayWithObjects:findMeServiceUUID,linkLossServiceUUID, nil];
                        [centralManager scanForPeripheralsWithServices:serviceArray options:scanOptions];
                      

                       

                      2. When found an peripheral i add the CBPeripheral* to an mutable array used as datasource for a table view displaying the scan results:

                       

                      - (void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
                      {
                        NSLog(@"INFO: Did discover peripheral <%@> with identifier <%@>", peripheral.name, peripheral.identifier);
                        [peripherals addObject:peripheral];
                        // Update UITableView
                        [self reloadTable];
                      }
                      

                       

                      3. Selected the peripheral in table view (set as CBPeripheral* selectedPeripheral) and connected to it with:

                       

                        NSDictionary* connectOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
                                                                                  forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey];
                        [centralManager connectPeripheral:selectedPeripheral options:connectOptions];
                      

                       

                      4. When connected I start the service discovery

                       

                      - (void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
                      {
                        NSLog(@"INFO: Did connect to peripheral <%@> with identifier <%@>", peripheral.name, peripheral.identifier);
                        isConnected = YES;
                        // Update the info UILabel
                        [self updateLabel];
                        // Start service discovery
                        [peripheral discoverServices:nil];
                      }
                      

                       

                      5. When a service is discoverd i start to discover the service characteristics:

                       

                      - (void) peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
                      {
                        NSLog(@"INFO: Did discover %d services on %@", (int)[peripheral services].count, [peripheral name]);
                        for(CBService *s in [peripheral services]) {
                          if([[s UUID] isEqual:findMeServiceUUID])
                            immediateAlertService = s;
                          if([[s UUID] isEqual:linkLossServiceUUID])
                            linkLossService = s;
                          NSLog(@"INFO: Did discover service %@ on %@", [s.UUID representativeString], [peripheral name]);
                          [peripheral discoverCharacteristics:[NSArray arrayWithObject:alertLevelCharacteristicUUID] forService:s];
                        }
                      }
                      

                       

                      6. When discoverd a characterisics for a service i store thr references to a variable.

                       

                      - (void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
                      {
                        NSLog(@"INFO: Did discover %d characteristics for service %@ on peripheral %@", (int)service.characteristics.count, service, peripheral);
                        for(CBCharacteristic *c in [service characteristics])
                        {
                          NSLog(@"INFO: Did discover characteristic %@ for service %@ on peripheral %@", [c.UUID representativeString], service, peripheral);
                          if([service isEqual:immediateAlertService] &&
                            [[c UUID] isEqual:alertLevelCharacteristicUUID])
                            immediateAlertAlertLevelCharacteristic = c;
                          else if([service isEqual:linkLossService] &&
                                  [[c UUID] isEqual:alertLevelCharacteristicUUID]) {
                            if(isBonded)
                              return;
                            linkLossAlertLevelCharacteristic = c;
                            if(linkLossAlertLevelCharacteristic)
                              [self writeLinkLossAlert:BT_ALERT_LEVEL_NONE];
                          }
                        }
                      }
                      

                       

                      7. As you can see if linkLossAlertLevelCharacteristic is discovered i immediately write BT_ALERT_LEVEL_NONE ( = 0 ) to it, to initialize bonding:

                       

                      - (void) writeLinkLossAlertLevelToTag:(UInt8) linkLossAlertLevel
                      {
                        NSData* data = [NSData dataWithBytes:&linkLossAlertLevel length:1];
                        [selectedPeripheral writeValue:data forCharacteristic:linkLossAlertLevelCharacteristic type:CBCharacteristicWriteWithResponse];
                      }
                      - (bool) writeLinkLossAlert:(UInt8)level
                      {
                        if(linkLossAlertLevelCharacteristic != nil) {
                          NSLog(@"INFO: Writes link loss alert %d to peripheral...", level);
                          [self writeLinkLossAlertLevelToTag:level];
                          return YES;
                        }
                        NSLog(@"ERROR: Couldn´t write to alert level on link loss service.");
                        return NO;
                      }
                      

                       

                      8. The "Pairing" dialog appears and is confirmed to pair with. But instead of pairing the write fails and there after i also get a disconnect with the timeout error.

                       

                      It works all fine until iOS 9 and i don't use any deprecated API's

                       

                      I logged the delegate callbacks from CBCentralManager and CBPeripheral:


                      2015-10-30 11:38:07.881 BLEControl[307:32547] INFO: Bluetooth is enabled

                      2015-10-30 11:38:14.423 BLEControl[307:32547] INFO: Start to scan for peripherals

                      2015-10-30 11:38:14.456 BLEControl[307:32547] INFO: Did discover peripheral <Torantrieb> with identifier <<__NSConcreteUUID 0x15d70340> 0545B850-B6BE-1BB9-10E7-80E3559AC9FB>

                      2015-10-30 11:38:18.129 BLEControl[307:32547] INFO: Stopped to scan for peripherals

                      2015-10-30 11:38:18.164 BLEControl[307:32547] INFO: Did connect to peripheral <Torantrieb> with identifier <<__NSConcreteUUID 0x15d70340> 0545B850-B6BE-1BB9-10E7-80E3559AC9FB>

                      2015-10-30 11:38:18.362 BLEControl[307:32547] INFO: Did discover 3 services on Torantrieb

                      2015-10-30 11:38:18.363 BLEControl[307:32547] INFO: Did discover service 1804 on Torantrieb

                      2015-10-30 11:38:18.364 BLEControl[307:32547] INFO: Did discover service 1802 on Torantrieb

                      2015-10-30 11:38:18.364 BLEControl[307:32547] INFO: Did discover service 1803 on Torantrieb

                      2015-10-30 11:38:18.366 BLEControl[307:32547] INFO: Did discover 0 characteristics for service <CBService: 0x15d85a00, isPrimary = YES, UUID = 1804> on peripheral <CBPeripheral: 0x15d85de0, identifier = 0545B850-B6BE-1BB9-10E7-80E3559AC9FB, name = Torantrieb, state = connected>

                      2015-10-30 11:38:18.367 BLEControl[307:32547] INFO: Did discover 1 characteristics for service <CBService: 0x15d8d5e0, isPrimary = YES, UUID = 1802> on peripheral <CBPeripheral: 0x15d85de0, identifier = 0545B850-B6BE-1BB9-10E7-80E3559AC9FB, name = Torantrieb, state = connected>

                      2015-10-30 11:38:18.367 BLEControl[307:32547] INFO: Did discover characteristic 2a06 for service <CBService: 0x15d8d5e0, isPrimary = YES, UUID = 1802> on peripheral <CBPeripheral: 0x15d85de0, identifier = 0545B850-B6BE-1BB9-10E7-80E3559AC9FB, name = Torantrieb, state = connected>

                      2015-10-30 11:38:18.367 BLEControl[307:32547] INFO: Did discover 1 characteristics for service <CBService: 0x15d8d620, isPrimary = YES, UUID = 1803> on peripheral <CBPeripheral: 0x15d85de0, identifier = 0545B850-B6BE-1BB9-10E7-80E3559AC9FB, name = Torantrieb, state = connected>

                      2015-10-30 11:38:18.369 BLEControl[307:32547] INFO: Did discover characteristic 2a06 for service <CBService: 0x15d8d620, isPrimary = YES, UUID = 1803> on peripheral <CBPeripheral: 0x15d85de0, identifier = 0545B850-B6BE-1BB9-10E7-80E3559AC9FB, name = Torantrieb, state = connected>

                      2015-10-30 11:38:18.370 BLEControl[307:32547] INFO: Writes link loss alert 0 to peripheral...

                      2015-10-30 11:38:22.354 BLEControl[307:32547] ERROR: Failed to write value for characteristic <CBCharacteristic: 0x15d8d890, UUID = 2A06, properties = 0xA, value = (null), notifying = NO>, reason: Error Domain=CBATTErrorDomain Code=15 "Encryption is insufficient." UserInfo={NSLocalizedDescription=Encryption is insufficient.}

                      2015-10-30 11:38:23.145 BLEControl[307:32547] ERROR: Did disconnect peripheral <Torantrieb>  with identifier <<__NSConcreteUUID 0x15d70340> 0545B850-B6BE-1BB9-10E7-80E3559AC9FB>: Error Domain=CBErrorDomain Code=6 "The connection has timed out unexpectedly." UserInfo={NSLocalizedDescription=The connection has timed out unexpectedly.} {

                          NSLocalizedDescription = "The connection has timed out unexpectedly.";

                      }

                       

                      Here is the full code of my Test-View Controller

                       

                      ViewController.h


                      #import <UIKit/UIKit.h>
                      #import <CoreBluetooth/CoreBluetooth.h>
                      @interface CBUUID (StringExtraction)
                      - (NSString *)representativeString;
                      @end
                      
                      @interface ViewController : UIViewController <UITableViewDelegate,UITableViewDataSource,CBCentralManagerDelegate,CBPeripheralDelegate>
                      @end
                      


                      ViewController.m

                       

                      #import "ViewController.h"
                      
                      #define findMeServiceUUID            [CBUUID UUIDWithString:@"1802"]
                      #define genericAccessServiceUUID      [CBUUID UUIDWithString:@"1800"]
                      #define linkLossServiceUUID          [CBUUID UUIDWithString:@"1803"]
                      #define deviceNameCharacteristicUUID  [CBUUID UUIDWithString:@"2A00"]
                      #define alertLevelCharacteristicUUID  [CBUUID UUIDWithString:@"2A06"]
                      #define BT_ALERT_LEVEL_NONE 0
                      #define BT_LEVEL_MILD 1
                      #define BT_ALERT_LEVEL_HIGH 2
                      #define BT_ALERT_LEVEL_RESERVED(LVL) LVL
                      
                      @implementation CBUUID (StringExtraction)
                      - (NSString *)representativeString;
                      {
                        NSData *data = [self data];
                      
                        NSUInteger bytesToConvert = [data length];
                        const unsigned char *uuidBytes = [data bytes];
                        NSMutableString *outputString = [NSMutableString stringWithCapacity:16];
                      
                        for (NSUInteger currentByteIndex = 0; currentByteIndex < bytesToConvert; currentByteIndex++)
                        {
                          switch (currentByteIndex)
                          {
                            case 3:
                            case 5:
                            case 7:
                            case 9:[outputString appendFormat:@"%02x-", uuidBytes[currentByteIndex]]; break;
                            default:[outputString appendFormat:@"%02x", uuidBytes[currentByteIndex]];
                          }
                      
                        }
                        return outputString;
                      }
                      @end
                      
                      @interface ViewController ()
                      @end
                      
                      @implementation ViewController {
                        NSMutableArray* peripherals;
                        BOOL isScanning;
                        BOOL isPairing;
                        BOOL isBonded;
                        BOOL isConnected;
                        BOOL hasFailed;
                      
                        CBCentralManager* centralManager;
                      
                        CBPeripheral* selectedPeripheral;
                        CBService *immediateAlertService;
                        CBCharacteristic *immediateAlertAlertLevelCharacteristic;
                      
                        CBService *linkLossService;
                        CBCharacteristic *linkLossAlertLevelCharacteristic;
                      
                        IBOutlet UILabel* labelPeripheral;
                        IBOutlet UIButton* buttonScan;
                        IBOutlet UITableView* tablePeripherals;
                      }
                      -(id)initWithCoder:(NSCoder *)aDecoder {
                        self = [super initWithCoder:aDecoder];
                        if(!self)
                          return self;
                      
                        peripherals = [[NSMutableArray alloc] init];
                        centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
                        return self;
                      }
                      - (void)viewDidLoad {
                        [super viewDidLoad];
                        [self updateLabel];
                      }
                      - (void)didReceiveMemoryWarning {
                        [super didReceiveMemoryWarning];
                      }
                      #pragma mark - BLE
                      -(void)startScan {
                        if(isScanning)
                          return;
                      
                        [centralManager stopScan];
                        [peripherals removeAllObjects];
                        [self reloadTable];
                      
                        NSDictionary* scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
                                                                                forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
                        NSArray* serviceArray = [NSArray arrayWithObjects:findMeServiceUUID,linkLossServiceUUID, nil];
                      
                        [centralManager scanForPeripheralsWithServices:serviceArray options:scanOptions];
                      
                        NSLog(@"INFO: Start to scan for peripherals");
                        isScanning = YES;
                      }
                      -(void)stopScan {
                      
                        /
                      
                        if(!isScanning)
                          return;
                      
                        [centralManager stopScan];
                        NSLog(@"INFO: Stopped to scan for peripherals");
                      
                        isScanning = NO;
                      }
                      -(void)pairPeripheral {
                      
                        if(!selectedPeripheral || isPairing)
                          return;
                      
                        isPairing = YES;
                        selectedPeripheral.delegate = self;
                      
                        [self updateLabel];
                      
                        [self connectPeripheral];
                      }
                      -(void)connectPeripheral {
                        if(!selectedPeripheral || isConnected)
                          return;
                      
                        NSDictionary* connectOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
                                                                                  forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey];
                        [centralManager connectPeripheral:selectedPeripheral options:connectOptions];
                      }
                      -(void)disconnectPeripheral {
                        if(!selectedPeripheral || !isConnected)
                          return;
                      
                        [centralManager cancelPeripheralConnection:selectedPeripheral];
                      }
                      -(void)alertPeripheral {
                        if(!selectedPeripheral || !isBonded)
                          return;
                      
                        [self writeImmediateAlert:BT_ALERT_LEVEL_RESERVED(3)];
                      }
                      - (void) writeLinkLossAlertLevelToTag:(UInt8) linkLossAlertLevel
                      {
                        NSData* data = [NSData dataWithBytes:&linkLossAlertLevel length:1];
                        [selectedPeripheral writeValue:data forCharacteristic:linkLossAlertLevelCharacteristic type:CBCharacteristicWriteWithResponse];
                      }
                      - (bool) writeLinkLossAlert:(UInt8)level
                      {
                        if(linkLossAlertLevelCharacteristic != nil) {
                          NSLog(@"INFO: Writes link loss alert %d to peripheral...", level);
                          [self writeLinkLossAlertLevelToTag:level];
                          return YES;
                        }
                        NSLog(@"ERROR: Couldn´t write to alert level on link loss service.");
                        return NO;
                      }
                      - (void) writeImmediateAlertLevelToTag:(UInt8) immediateAlertLevel
                      {
                        NSData* data = [NSData dataWithBytes:&immediateAlertLevel length:1];
                        [selectedPeripheral writeValue:data forCharacteristic:immediateAlertAlertLevelCharacteristic type:CBCharacteristicWriteWithoutResponse];
                      }
                      - (bool) writeImmediateAlert:(UInt8)level
                      {
                        if(immediateAlertAlertLevelCharacteristic != nil) {
                          NSLog(@"INFO: Writes immediate alert %d to tag...", level);
                          [self writeImmediateAlertLevelToTag:level];
                          return YES;
                        }
                        NSLog(@"INFO: Couldn´t write to alert level on immediate alert service.");
                        return NO;
                      }
                      #pragma mark - CentralManager delegate
                      - (void) centralManagerDidUpdateState:(CBCentralManager *)central
                      {
                        if ([central state] == CBCentralManagerStatePoweredOn)
                          NSLog(@"INFO: Bluetooth is enabled");
                        else
                        {
                          NSLog(@"WARNING: Bluetooth is not enabled");
                          [labelPeripheral setText:@"Bluetooth is not enabled!"];
                        }
                      }
                      - (void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
                      {
                        NSLog(@"INFO: Did discover peripheral <%@> with identifier <%@>", peripheral.name, peripheral.identifier);
                        [peripherals addObject:peripheral];
                        [self reloadTable];
                      }
                      - (void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
                      {
                        NSLog(@"INFO: Did connect to peripheral <%@> with identifier <%@>", peripheral.name, peripheral.identifier);
                      
                        isConnected = YES;
                        [self updateLabel];
                      
                        [peripheral discoverServices:nil];
                      }
                      - (void) centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
                      {
                        isConnected = NO;
                        if(error) {
                          NSLog(@"ERROR: Did disconnect peripheral <%@>  with identifier <%@>: %@ %@", peripheral.name, peripheral.identifier, error, [error userInfo]);
                      
                          if(isPairing) {
                            hasFailed = YES;
                            isPairing = NO;
                            [self updateLabel];
                          }
                          return;
                        }
                        [self updateLabel];
                        NSLog(@"INFO: Did disconnect peripheral <%@> with identifier <%@>", peripheral.name, peripheral.identifier);
                      }
                      - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
                        isPairing = NO;
                        [self updateLabel];
                      
                        if(error) {
                          NSLog(@"ERROR: Did failed to connect to peripheral <%@>  with identifier <%@>: %@ %@", peripheral.name, peripheral.identifier, error, [error userInfo]);
                          return;
                        }
                        NSLog(@"WARNING: Did failed to connect to peripheral <%@>  with identifier <%@>", peripheral.name, peripheral.identifier);
                      }
                      #pragma mark - Peripheral delegate
                      - (void) peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
                      {
                        NSLog(@"INFO: Did discover %d services on %@", (int)[peripheral services].count, [peripheral name]);
                        for(CBService *s in [peripheral services]) {
                          if([[s UUID] isEqual:findMeServiceUUID])
                            immediateAlertService = s;
                      
                          if([[s UUID] isEqual:linkLossServiceUUID])
                            linkLossService = s;
                      
                          NSLog(@"INFO: Did discover service %@ on %@", [s.UUID representativeString], [peripheral name]);
                          [peripheral discoverCharacteristics:[NSArray arrayWithObject:alertLevelCharacteristicUUID] forService:s];
                        }
                      }
                      - (void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
                      {
                        NSLog(@"INFO: Did discover %d characteristics for service %@ on peripheral %@", (int)service.characteristics.count, service, peripheral);
                        for(CBCharacteristic *c in [service characteristics])
                        {
                          NSLog(@"INFO: Did discover characteristic %@ for service %@ on peripheral %@", [c.UUID representativeString], service, peripheral);
                          if([service isEqual:immediateAlertService] &&
                            [[c UUID] isEqual:alertLevelCharacteristicUUID])
                            immediateAlertAlertLevelCharacteristic = c;
                      
                          else if([service isEqual:linkLossService] &&
                                  [[c UUID] isEqual:alertLevelCharacteristicUUID]) {
                         
                            if(isBonded)
                              return;
                         
                            linkLossAlertLevelCharacteristic = c;
                            if(linkLossAlertLevelCharacteristic)
                              [self writeLinkLossAlert:BT_ALERT_LEVEL_NONE];
                         
                          }
                        }
                      }
                      - (void) peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
                      {
                        NSLog(@"INFO: Did update value for characteristic %@, new value: %@, error: %@", characteristic, [characteristic value], error);
                      }
                      - (void) peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
                      {
                        if (error)
                        {
                          NSLog(@"ERROR: Failed to write value for characteristic %@, reason: %@", characteristic, error);
                        }
                        else
                        {
                          NSLog(@"INFO: Did write value for characterstic %@, new value: %@", characteristic, [characteristic value]);
                      
                          isPairing = NO;
                          isBonded = YES;
                      
                          [self updateLabel];
                        }
                      }
                      #pragma mark - UI
                      -(IBAction)onScanButton:(id)sender {
                      
                        if(!isScanning) {
                          [self startScan];
                          [buttonScan setTitle:@"Stop" forState:UIControlStateNormal];
                        }
                        else {
                          [self stopScan];
                          [buttonScan setTitle:@"Start" forState:UIControlStateNormal];
                        }
                        [self updateLabel];
                      }
                      -(IBAction)onConnectButton:(id)sender {
                        [self connectPeripheral];
                      }
                      -(IBAction)onDisconnectButton:(id)sender {
                        [self disconnectPeripheral];
                      }
                      -(IBAction)onAlertButton:(id)sender {
                        [self alertPeripheral];
                      }
                      -(void) updateLabel {
                        if(!selectedPeripheral) {
                          if(!isScanning)
                            [labelPeripheral setText:@"Press start to scan"];
                          else
                            [labelPeripheral setText:@"Scanning..."];
                          return;
                        }
                      
                        if(hasFailed) {
                          [labelPeripheral setText:[NSString stringWithFormat:@"%@ pairing failed", selectedPeripheral.name]];
                          return;
                        }
                      
                        if(isBonded) {
                          [labelPeripheral setText:[NSString stringWithFormat:@"%@ bonded", selectedPeripheral.name]];
                          return;
                        }
                      
                        if(isConnected) {
                          [labelPeripheral setText:[NSString stringWithFormat:@"%@ connected", selectedPeripheral.name]];
                          return;
                        }
                        if(isPairing) {
                          [labelPeripheral setText:[NSString stringWithFormat:@"%@ pairing...", selectedPeripheral.name]];
                          return;
                        }
                      }
                      #pragma Mark - Validating
                      -(CBPeripheral*)getPeripheral:(NSInteger)arrayIndex {
                        CBPeripheral* peripheral = NULL;
                      
                        if(!peripherals)
                          NSLog(@"FATAL: Peripherals array is NULL");
                        else {
                          if(peripherals.count < arrayIndex)
                            NSLog(@"FATAL: Peripherals array length is too short.");
                      
                      
                          peripheral = [peripherals objectAtIndex:arrayIndex];
                          if(!peripheral)
                            NSLog(@"FATAL: Peripheral is NULL.");
                        }
                      
                        return peripheral;
                      }
                      # pragma mark - TableView thread synchronization
                      -(void)reloadTable {
                      
                        [tablePeripherals performSelectorOnMainThread:@selector(reloadData)
                                                          withObject:nil
                                                        waitUntilDone:YES];
                      }
                      #pragma mark - TableView dataSource and delegate
                      - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
                        return 64;
                      }
                      - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
                        return 1;
                      }
                      - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
                        if(!peripherals)
                          return 0;
                      
                        return [peripherals count];
                      }
                      - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
                      
                      
                        selectedPeripheral = [self getPeripheral:indexPath.item];
                        if(!selectedPeripheral)
                          return;
                      
                        if(isScanning)
                          [self onScanButton:buttonScan];
                        [self pairPeripheral];
                      }
                      -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
                        UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"SettingsCell"];
                        if(!cell) {
                          cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SettingsCell"];
                          cell.selectionStyle = UITableViewCellSelectionStyleBlue;
                        }
                      
                        CBPeripheral* peripheral = [self getPeripheral:indexPath.item];
                        if(!peripheral) {
                          [cell.textLabel setText:@"<Unexpected error>"];
                          return cell;
                        }
                      
                        [cell.textLabel setText:peripheral.name];
                        return cell;
                      }
                      @end
                      
                  • Re: Pairing issues with IOS9 Beta 5
                    sim.7777 Level 1 Level 1 (0 points)

                    We see the same issue as well. BLE Pairing with Ipad 3 and BT LE 4.0 Blood Pressure device fails after we try to update notification .

                    The same works on iOS 9.0 on the iPhone 5s. The error returned is -

                     

                    Error code was Error Domain=CBATTErrorDomain Code=15 "Encryption is insufficient." UserInfo={NSLocalizedDescription=Encryption is insufficient.}