Hi,
I'm having problems discovering services for peripherals that have been retrieved using myCentral:retrievePeripheralsWithIdentifiers. I have no problem discovering serivces (and characteristics) for peripherals that have been identified with myCentral:scanForPeripheralsWithServices. I've searched tha varioius forums high and low and see no discussions that indicate that there might be a problem with retrieving peripherals so I assume it is something wrong that I'm doing but I just don't see what. Any pointers would be welcome.
My environment is: iPhone 6 running iOS 8.4, xcode 6.4 and a T.I. CC2541-based peripheral
The scanning sequence works fine as follows:
Initialise CBCentralManager and wait for confirmation that BLE is powered up and ready:
eventQueue = dispatch_queue_create("com.ekko-tech.mycentral", DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(eventQueue, dispatch_get_main_queue());
[self setCentralManager:[[CBCentralManager alloc] initWithDelegate:self queue:eventQueue options:bleInitOptions]];
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
.....
else if ([central state] == CBCentralManagerStatePoweredOn) {
.....
Scan for peripherals providing the service I'm looking for:
NSArray *services = [NSArray arrayWithObject:
[CBUUID UUIDWithString:
[[[[[self appContext] objectForKey:@"gampResources"] objectForKey:@"Services"]
objectForKey:@"Gamp"]
objectForKey:@"kGAServiceUUID"]]];
[centralManager scanForPeripheralsWithServices:services options:bleScanOptions];
As peripheral(s) are discovered, store the one selected by the user (CBPeriferal and NSUID) in local variables. The local variables are held in a global dictionary - ioContext:
NSArray *dp = [[sc appContext] objectForKey:@"discoveredPeripherals"];
assert(selectedCellIndex < [dp count]);
[[sc ioContext] setObject:[dp objectAtIndex:selectedCellIndex] forKey:@"thisPeripheral"];
[[sc ioContext] setObject:[[dp objectAtIndex:selectedCellIndex] identifier] forKey:@"thisPeripheralUUID"];
After the selected peripheral has been sucessfully connected to, store a string representation of the NSUUID in userDefaults:
NSString *uuidstr = [(NSUUID*)[[[self ioContext] objectForKey:@"thisPeripheral"] identifier] UUIDString];
assert(uuidstr != nil);
[[self userDefaults] setValue: uuidstr forKey:@"kLastConnectedPeripheralUUID"];
[[self userDefaults] synchronize];
Discovering services and characteristics for the above scanned peripheral works just fine. However, the next time the application is run, it will use the NSUUID stored in userDefaults to retrieve that peripheral (before this is eecuted, the initialisation sequence identical to the above is executed - not shown here for brevity):
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:[[self userDefaults] objectForKey:@"kLastConnectedPeripheralUUID"]];
assert(uuid != nil);
NSArray *knownPeripherals;
knownPeripherals = [[self centralManager] retrievePeripheralsWithIdentifiers:[NSArray arrayWithObjects:uuid, nil]];
if ([knownPeripherals count] > 0) {
[[self ioContext] setValue:[knownPeripherals objectAtIndex:0] forKey:@"thisPeripheral"];
[[self ioContext] setValue:[[knownPeripherals objectAtIndex:0] identifier] forKey:@"thisPeripheralUUID"];
/
[[self centralManager] connectPeripheral:[[self ioContext] objectForKey:@"thisPeripheral"] options:bleConnectOptions];
}
The retrieved peripheral connects just fine but subsequent attempts to discover services fail. Specifically, the delegate callback didDiscoverServices is never called:
- (void)doDiscoverService:(NSString *)service {
CBPeripheral *per = [[self ioContext] objectForKey:@"thisPeripheral"];
CBUUID *suuid = [CBUUID UUIDWithString:[[[[[self appContext] objectForKey:@"gampResources"] objectForKey:@"Services"] objectForKey:service] objectForKey:@"kGAServiceUUID"]];
assert(per != nil);
assert(suuid != nil);
[[self ioContext] setValue:suuid forKey:@"thisServiceUUID"];
NSArray *svcArray = [NSArray arrayWithObjects:suuid, nil];
[per discoverServices:svcArray];
}
Since the first service that I want to discover is the battery service, the passed-in string in the above is "Battery"
Regards,
ac