Search code examples
iosobjective-cxcodebluetooth-lowenergycore-bluetooth

BLE Characteristic not retained


I am writing an application which communicates with multiple (between 5 & 10) identical BLE devices. Each BLE device has multiple characteristics some are static, some update and others can be written to.

The application has multiple ViewControllers embedded within a Navigation Controller and is for IOS devices (specifically IOS 8+ and iPhone 6).

In order to make the program efficient and to work with CoreBluetooth I have created to classes to manage the BLE interaction:

  1. BLE Control Class - Which scans for and connects the correct BLE devices.

and

  1. BLE Services Class - Once connected scans the characteristics and sets them appropriately according to their type.

Data sent by a peripheral and received by the manager for known connected characteristics is then stored in a back-end SQLite db.

The issue I am facing is writing back to a connected peripherals characteristic. I have collected the characteristic within a CBCharacteristic, but it does not persist within the class when I attempt to write to it the value of the CBCharacteristic is NULL.

Following is a summary of the code I have used:

CBCharacteristic Definition within the BLEServicesClass

#import "BLEServicesClass.h"
#import "BLEControlClass.h"

NSString *srModeUUIDString = @"346D0003-12A9-11CF-1279-81F2B7A91332";

@interface BLEServicesClass() <CBPeripheralDelegate> {

@private
    CBPeripheral        *servicePeripheral;
    CBCharacteristic    *srModeCharacteristic;
@end

didDiscoverCharacteristicForService

- (void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error;
{

    NSArray     *characteristics    = [service characteristics];
    CBCharacteristic *characteristic;

        if ([[characteristic UUID] isEqual:srModeUUID]) {
            NSLog(@"didDiscoverServices - Mode Characteristic");
            srModeCharacteristic = characteristic;
        }

To write to a characteristic

-(void)writeCharacteristic:(CBCharacteristic *)whichCharacteristic data:(NSData*)data device:(NSString *)device
{

    NSArray   *devices;
    devices = [[BLEControlClass sharedInstance] connectedPeripherals];

    int i;
    for (i = 0; i < [[[BLEControlClass sharedInstance] connectedPeripherals] count]; i++) {
        CBPeripheral *peripheral=[[[BLEControlClass sharedInstance] connectedPeripherals] objectAtIndex:i];
        peripheral.delegate=self;
        NSString *tesfordevice = peripheral.name;

        if (tesfordevice == device) {
            [whichCharacteristic.service.peripheral writeValue:data forCharacteristic:whichCharacteristic type:CBCharacteristicWriteWithResponse];
        }
    }
}

This is called by:

-(void)writeModeCharacteristic:(NSData*)data :(NSString *)device
{
    [self writeCharacteristic:srModeCharacteristic data:data device:device];
}

My issue is that the srModeCharacteristic is initially set correctly when its is discovered but later is NULL.

Any help please?


Solution

  • I recommend always resolving the characteristics on demand, i.e. by iterating and taking the first with the matching UUID. If there are none, issue a new scan – same for the services.

    That way your program will easily survive reconnects.