在重新连接时,iPhone不会在蓝牙LE标签上发现服务

Man*_*ran 9 iphone xcode bluetooth ios5 core-bluetooth

我正在开发适用于iOS的蓝牙LE应用程序.我在iOS中使用Core Bluetooth框架来处理所有通信.

问题与描述:

当我使用单个标签时,尽管存在大量连接和断开连接,但单个标签可以无缝连接,并且手机会发现它的服务.

此外,当多个蓝牙LE标签首次连接时,它们无缝连接,手机会发现其服务.

当标签断开然后重新连接到手机时,标签连接正常.但是两个标签中的一个(任一个)似乎没有宣传其服务.即,当应用程序打开并且标记重新连接时,DiscoverServices方法不会调用didDiscoverServices委托.

为什么只有在与多个设备连接时才会发生这种情况.

我已正确设置了peripheral.delegate.我已经尝试了一切,包括重复重新连接,重复发送到标签的DiscoverServices.似乎没什么用.

如何重新连接到手机的多个标签,仍然可以发现所有服务.

请帮忙

谢谢,
Manju

小智 21

我有同样的问题,但意识到,我是不设置delegateCBPeripheral之后didConnectPeripheral被调用.

- (void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    NSLog(@"Peripheral Connected: %@", peripheral.name);

    peripheral.delegate = self;

    if (peripheral.services) {
        [self peripheral:peripheral didDiscoverServices:nil];
    } else {
        [peripheral discoverServices:@[[CBUUID UUIDWithString:CUSTOM_UUID]]];
    }  
}
Run Code Online (Sandbox Code Playgroud)


P.L*_*.L. 14

我面临类似的问题,CoreBluetooth连接到蓝牙LE设备,在我的情况下从我的Mac(中央)连接到iOS设备(外围设备).

如果我找到你的正确,模式是非常一致的,我第一次运行我的Mac应用程序进行调试时,它总是检测到并连接到任何蓝牙LE设备(外围设备),最重要的是,它也发现他们的服务/特性很好.问题从第二次运行开始(例如,更改一些代码,点击cmd-R重新启动调试).中央仍检测外围设备并连接到它们,但是,它无法发现任何服务/特征.换句话说,委托peripheral:didDiscoverServices:peripheral:didDiscoverCharacteristicsForService:error:永远不会被调用.

经过大量试验和错误后的解决方案非常简单.似乎CoreBluetooth缓存servicescharacteristics仍然连接的外围设备,虽然本地看起来它已经断开连接到应用程序,外围设备仍然保持与系统的蓝牙连接.对于这些类型的连接,不需要(重新)发现服务和特征,只需直接从外围对象访问它们,检查nil是否应该发现它们.此外,如上所述,由于外围设备处于连接之间的状态,因此最好cancelPeripheralConnection:在尝试连接之前调用.它的要点如下,假设我们已经发现连接到的外围设备:

-(void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    [central cancelPeripheralConnection:peripheral]; //IMPORTANT, to clear off any pending connections    
    [central connectPeripheral:peripheral options:nil];
}

-(void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    peripheral.delegate = self;

    if(peripheral.services)
        [self peripheral:peripheral didDiscoverServices:nil]; //already discovered services, DO NOT re-discover. Just pass along the peripheral.
    else
        [peripheral discoverServices:nil]; //yet to discover, normal path. Discover your services needed
}

-(void) peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    for(CBService* svc in peripheral.services)
    {
        if(svc.characteristics)
            [self peripheral:peripheral didDiscoverCharacteristicsForService:svc error:nil]; //already discovered characteristic before, DO NOT do it again
        else
            [peripheral discoverCharacteristics:nil
                                     forService:svc]; //need to discover characteristics
    }
}

-(void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    for(CBCharacteristic* c in service.characteristics)
    {
        //Do some work with the characteristic...
    }
}
Run Code Online (Sandbox Code Playgroud)

这适用于Mac应用程序中的CBCentralManager.从未在iOS中测试它,但我认为它应该非常相似.


Man*_*ran 1

事实证明,我在“ didDiscovercharacteristicsForService ”委托方法中向设备发出了命令,导致连接不稳定。

如果您遇到类似的问题,我建议您让委托方法在没有任何干预(任何形式)的情况下完成,并将 CBPeripheral 传递给您设计的另一个函数,以传递任何值/向设备发出命令。

不管怎样,谢谢威尔姆森。

步骤如下..
1> 搜索标签,
2> 如果在范围内,连接到标签
3> 如果已连接,调用 DISCOVER 服务方法(不要中断)
4> 在 DidDiscoverServices 中,调用 DISCOVER 特征方法
..
在 DidDiscoverCharacteristics 中方法,等到发现所有特征..然后,最后,在代码中调用一个函数来执行必要的设置..
...
代码示例

-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{

    for (int i=0; i < peripheral.services.count; i++) {
        CBService *s = [peripheral.services objectAtIndex:i];
        printf("Fetching characteristics for service with UUID : %s\r\n",[self CBUUIDToString:s.UUID]);
        [peripheral discoverCharacteristics:nil forService:s];
    }

}


- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{        
    if (!error)
    {
        CBService *s = [peripheral.services objectAtIndex:(peripheral.services.count - 1)];
        if([self compareCBUUID:service.UUID UUID2:s.UUID])
        {
           // This is when the **Tag** is completely connected to the Phone and is in a mode where it can accept Instructions from Device well.

            printf("Finished discovering characteristics");
           // Now Do the Setup of the Tag
            [self setupPeripheralForUse:peripheral];

        }
    }

    else
    {
        printf("Characteristic discorvery unsuccessfull !\r\n");
    }
}

-(void) setupPeripheralForUse:(CBPeripheral *)peripheral
{

    // DO all your setup in this function. Separate Perpiheral Setup from the process that synchronizes the tag and the phone. 

}
Run Code Online (Sandbox Code Playgroud)