阻止与ios附件的通信

Apple似乎建议使用runloops与外部附件进行数据通信。 但是,除非我遗漏了某些内容,否则runloops不适合某些类型的通信。

我们有一个-experimental-附件,我们需要发送任意数量的字节(最多,比如1024),然后是附件处理数据(可变延迟,比如在1ms到1000ms之间),然后是附件的可变长度响应(最多1024个字节)。

我们想开发一个静态库(框架)来与附件进行通信。 基本上,这个库将有一个函数,它将NSArray或NSMutableArray作为输入,并返回包含响应的NSArray或NSMutableArray。

问题是推荐的runloops策略不适合这种类型的应用程序。 在静态库函数中,在准备好要传输的数据并调度传输之后,我们必须进入某种“等待”状态。 但是,此等待状态不能基于轮询方法(例如等待接收路由设置的-synchronized-变量),因为接收例程永远不会执行(因为它们在同一个线程上) 。

如果我们不使用runloops,那么我们就不知道何时读取数据,因为我们不知道数据何时到达。

关于如何解决这个问题的任何想法或建议? 那里有什么例子吗?

这不是runLoop或ExternalAccessories问题。 这是每日OOP问题。

最好的方法是创建一个可以写入outputStream并等待响应的Communication对象。 使用@protocols执行此操作! (事件监听器驱动程序)

尝试这个:

首先,您必须将输入/输出流附加到runLoop:

[[session inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [[session inputStream] open]; [[session outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [[session outputStream] open]; 

成为他们的代表:

 [[session outputStream] setDelegate:self]; [[session inputStream] setDelegate:self]; 

成为委托后,您必须实现此方法:

 -(void)stream:handleEvent:{}; 

这是将数据写入流的命令:

 /* data is a NSData containing data to transmit. */ [[session outputStream] write:(uint8_t *)[data bytes] maxLength:[data length]]; 

这是一个示例代码,(一旦创建了会话,而我们期望的答案是一个字节):

在Comm.h中:

 /* Define your protocol */ @protocol CommDelegate  -(void)byteReceived: (char) byte; @end @interface Comm  { [...] id delegate; } @end @property (nonatomic, retain) id delegate; 

在Comm.m:

 @implementation Comm [...] -(id)init { [...] delegate = nil; [...] } -(void)write: (NSData *) data { [[session outputStream] write:(uint8_t *)[data bytes] maxLength:[data length]]; } -(void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)_event { switch (_event) { case NSStreamEventHasBytesAvailable: /* This part will be executed every time your rx buffer contains at least 1 byte */ switch(state) { uint8_t ch; /* Read byte per byte */ [stream read:&ch maxLength:1]; /* now ch contains a byte from your MFI device ** and 'read' function decrease the length of the rx buffer by -1 */ /* Now you can notify this to the delegate */ if(self.delegate != nil) [delegate byteReceived: ch]; } break; } } 

your_app_controller.h:

 @interface MyApp : UIViewController  { Comm comm; } @end 

your_app_controller.m:

 @implementation MyApp -(id)init { [...] comm = [[Comm alloc] init]; [comm setDelegate: self]; /* Now your thread is listening your communication. */ } -(void)write { byte out = 'X'; [comm write: [NSData dataWithBytes: &out length: 1]]; } -(void)bytereceived:(char)reply { if(reply == 'Y') { [self write]; //[self performSelectorInBackground:@selector(write) withObject:nil]; IT'S BETTER!!! } } @end 

希望这可以帮助!