2017-02-09 76 views
1

我目前正在与CBPeripheralDelegate在iOS设备和Bluetooth Low Energy USB加密狗之间交换消息。我必须实现使用串行仿真服务写入数据字节的方法sendMessage:。此方法必须发送一个15字节(或更少)的帧,在发送下一个消息之前等待加密狗的确认。阻止for循环,直到委托方法被触发

下面是我的代码:

- (void)sendMessage:(NSData *)message { 
    NSArray *chuncks = [self splitMessage:message]; 
    for (NSUInteger i = 0; i < chunks.count; i++) { 
     NSData *chunk = [chunks objectAtIndex:i]; 
     [self sendChunk:chunk withId:i ofChunks:chances.count]; 
     // Wait for the ack to be received 
    } 
} 

- (void)sendChunk:(NSData *)chunk withId:(NSInteger)id ofChunks:(NSInteger)count { 
    NSMutableData *frame = [NSMutableData new]; 
    // Here I build my frame, adding header, current chunk ID and total number of chunks, then I call... 
    [serialEmulationService writeValue:frame forCharacteristic:serialEmulationServiceCharacteristic type:CBCharacteristicWriteWithResponse]; 
} 

现在问题:sendMessage:方法中的for循环必须被阻止,直到外围不会超时收到ACK,可能。这个确认是在委托方法- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error内收到的,所以在这里我必须重新启动以前阻止的for循环。

这种特殊情况的最佳做法是什么?我想使用GCD的信号量,但我无法弄清楚如何实现同步调用,也无法理解任何解释此技术的在线示例。

有人能帮我一下吗?

回答

1

如何跳过for循环完全...

@property (nonatomic) NSMutableArray *chunks; 
@property (nonatomic) NSInteger chunkId; 

- (void)sendMessage:(NSData *)message { 
    self.chunks = [[self splitMessage:message] mutableCopy]; 
    self.chunkId = 0; 

    [self sendNextChunk]; 
} 

- (void sendNextChunk { 

    NSData * chunk = self.chunks.firstObject; 

    if chunk == nil { 
     return 
    } 

    [self.chunks removeObjectAtIndex: 0]; 
    [self sendChunk:chunk withId:chunkId++ ofChunks:chances.count]; 
}  


- (void)sendChunk:(NSData *)chunk withId:(NSInteger)id ofChunks:(NSInteger)count { 
    NSMutableData *frame = [NSMutableData new]; 
    // Here I build my frame, adding header, current chunk ID and total number of chunks, then I call... 
    [serialEmulationService writeValue:frame forCharacteristic:serialEmulationServiceCharacteristic type:CBCharacteristicWriteWithResponse]; 
} 

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error { 
    [self sendNextChunk]; 
} 
+0

很容易的,谢谢。最简单直接的方法。只需稍加说明:需要为原始“块”数组大小定义一个属性,因为它在每个块发送时都会减少。 – Dree

0

该方法将使用Notification。创建separate method以运行您的for loop。此方法将观察者为Notification,内部为delegate方法后Notification。在sendMessage:不断添加消息到属性。