Search code examples
iosbtle

Make synchronized call with connectPeripheral IOS BTLE


The method connectPeripheral is defined in a class with CBCentralManagerDelegate. I need to call connectPeripheral from the table view controller when didSelectRowAtIndexPath is selected. Once the peripheral is connected it should continue to execute remaining lines of code in the view controller. I am able to connect to the Peripheral. But before the connection is complete it executes the remaining section of the code. Since the peripheral is not yet connected it does not do the necessary job.

I used dispatch_sync to ensure that the connection is established and then the remaining code is executed but it doesn't work. How can I get around this problem? I am relatively new to IOS programming. Any inputs is highly appreciated.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    CBPeripheral    *peripheral = nil;
    NSArray         *devices = [[NSArray alloc] init];

    switch (indexPath.section) {
            case 0: {
                devices = [[BTLECentralManager sharedInstance] foundPeripherals];
                peripheral = (CBPeripheral *)[devices objectAtIndex:indexPath.row];
                    dispatch_sync(syncConnection, ^{
                        [[BTLECentralManager sharedInstance] connectPeripheral:peripheral];
                        activePeripheral = [self serviceForPeripheral:peripheral];
                        NSLog(@"Active Peripheral %@",activePeripheral);
                        [activePeripheral getTimeDate];
                    });

                break;
                }
            default:
            break;
        }
}

Solution

  • The request to connect with the peripheral is an asynchronous process. You cannot just wrap that in a dispatch_sync to make it synchronous. (And you don't want to make it synchronous, anyway.)

    That synchronous dispatch of the connectPeripheral is merely synchronously dispatching the request to connect to that peripheral, but doesn't change the inherently asynchronous nature of the connection process, itself. In fact, you generally don't want to dispatch these asynchronous requests to your own background queue. Apple provided a nice asynchronous interface, so you go ahead use it from the main thread.

    While you, theoretically, could make a synchronous interface for this connection process, you should not do so. Instead, you should embrace the asynchronous nature of the interface. Either implement the delegates, or possibly wrap the CBCentralManager in some object that provides a block-based interface.