2014-06-11 157 views
0

当通过BLE通知接收到多个数据包时,iOS只允许我访问发送的最终数据包。我正在使用YMSCoreBluetooth连接到具有多种服务的BLE外设,每种服务都具有多种特性。我连接到外围设备,发现服务并发现这些服务的特征,而不会出现问题。我的目标是订阅某个特征的通知,并通过通知接收一系列数据包。我的订阅是成功的,我可以看到我的代码中使用NSLog,我收到包含数据的通知。问题是,当我从每个通知中访问数据时,每个通知都只给出最后一个数据包中包含的数据。通过BLE通知接收数据包

我的用于接收通知的代码如下:

- (void)notifyCharacteristicHandler:(YMSCBCharacteristic *)characteristic error:(NSError *)error 
{ 
    if (error) { 
     NSLog(@"Error: Error in handling notification.\n%@", error); 
    } 
    else if ([characteristic.name isEqualToString:@"InterestingChar"]) { 
     if (self.firstNotify) { 
      self.mutableData = [[NSMutableData alloc] init]; 
      self.firstNotify = NO; 
     } 
     NSData *data = [[NSData alloc] init]; 
     data = characteristic.cbCharacteristic.value; 

     [self.mutableData appendData:data]; 

     self.notifyCounter++; 
     NSLog(@"Notify received! Count: %ld \nData =%@",(long)self.notifyCounter,self.mutableData); 
    } 
    else NSLog(@"Other notification received"); 
} 

例如,如果我收到5个通知与以下数据:

1 ababababab

2 bcbcbcbcbc

3 cdcdcdcdcd

4 dedededede

5 efefefefef

我的NSLog将打印出efefefefef用于第二第一通知数据,efefefefef efefefefef等附加的最后一个数据值对于每个后续通知。

我试图尽快使用BLE从外设发送通知。连接间隔在20ms到40ms之间(iOS要求至少20ms的范围),每个连接间隔发送三个数据包。

编辑:

Paulw11的建议工作得很好。我通过修改YMSCB'didUpdateValueForCharacteristic'方法来解决这个问题,以获取特征值并将其与指向特征本身的指针一起传递给'notifyCharacteristicHandler'方法。修订后的方法现在看起来如下:

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { 
    __weak YMSCBPeripheral *this = self; 
    NSData *value = characteristic.value; 
    _YMS_PERFORM_ON_MAIN_THREAD(^{ 
     YMSCBService *btService = [this findService:characteristic.service]; 
     YMSCBCharacteristic *yc = [btService findCharacteristic:characteristic]; 

     if (yc.cbCharacteristic.isNotifying) { 
      [btService notifyCharacteristicHandler:yc value:value error:error]; 

     } else { 
      if ([yc.readCallbacks count] > 0) { 
       [yc executeReadCallback:characteristic.value error:error]; 
      } 
     } 

     if ([this.delegate respondsToSelector:@selector(peripheral:didUpdateValueForCharacteristic:error:)]) { 
      [this.delegate peripheral:peripheral didUpdateValueForCharacteristic:characteristic error:error]; 
     } 
    }); 
} 

你显然还需要修改“notifyCharacteristicHandler”的方法来接受新的说法。

+0

由于data ='characteristic.cbCharacteristic.value','NSData'的alloc/init是无用的。加上它不应该没有“characeteristic.value”?错字错误? – Larme

+0

这是一个YMSCBCharacteristic,它有一个CBCharacteristic作为一个属性,它又有一个值 – jrisberg

回答

1

查看YMSCoreBluetooth库的内部didUpdateValueForCharacteristic委托方法,它使用“在主线程上执行”将数据发送到您的方法,并且它不捕获数据 - 它只是发送对该特征的引用。此外,它通过在主线程上执行线性搜索来执行特征的“findCharacteristic”,即使在当前线程上输入委托方法时可以立即执行此操作。当然,这不会是一个非常大的阵列,但似乎这个库并没有创造出性能的头脑。

我怀疑你有一个计时问题 - 当你的方法执行特性中的数据时已经被覆盖。如果你能够控制你的外围设备,那就慢下来进行测试,看看问题是否消失。

如果是计时相关,那么你可以尝试直睿蓝牙实现,或者尝试修改YMSCoreBluetooth使得它的数据更早捕获 - 也许,如果它产生在didUpdateValueForCharacteristic开始外围的副本,并发送那对你的方法来说它会起作用。

+0

你完全正确。发布后,我放慢了周边通知,就像您在这里所建议的那样,数据开始按照预期以非常低的速度开始。我一直在通过YMS寻找解释,但还没有找到你所做的。谢谢!当我找出我需要为后代修复哪些修复时,我会编辑原始帖子。 – jrisberg