外部附件流在100%的时间内无法正常工作

问题描述:

输入和输出流始终打开,并使用正确的NSStreamEvent代码(NSStreamEventOpenCompleted)调用相应的委托方法。但是,在某些openSession尝试中,流成功打开,但它们不起作用。有时我只能写入输出流,但我无法从输入流中读取数据。有时我无法读写。外部附件流在100%的时间内无法正常工作

有没有人遇到这个问题或有任何想法,为什么发生这种情况?任何帮助表示赞赏。谢谢。

下面是一些相关的代码

- (BOOL)openSession 
{ 
    _session = [[EASession alloc] initWithAccessory:_selectedAccessory 
             forProtocol:_protocolString]; 

    if (!_session) 
     return false; 

    [_selectedAccessory setDelegate:self]; 
    [[_session inputStream] setDelegate:self]; 
    [[_session outputStream] setDelegate:self]; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{ 

     [[_session inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] 
              forMode:NSDefaultRunLoopMode]; 
     [[_session inputStream] open]; 

     [[_session outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] 
              forMode:NSDefaultRunLoopMode]; 
     [[_session outputStream] open]; 

     [[NSRunLoop currentRunLoop] run]; 
    }); 

    return true; 
} 

- (void)setupControllerForAccessory:(EAAccessory *)accessory withProtocolString:(NSString *)protocolString 
{ 
    _selectedAccessory = accessory; 
    _protocolString = [protocolString copy]; 
} 

/** 
* There is something weird happening here too, this always get called twice when an accessory 
* gets connected. Once without a protocol string and once with a protocol string. I just 
* ignore the one without a protocol string. 
*/ 
- (void)accessoryConnected:(NSNotification *)notification 
{ 
    EAAccessory *connectedEA = [notification.userInfo objectForKey:@"EAAccessoryKey"]; 

    // Check to see if the connected EA has a protocol string 
    if ([[connectedEA protocolStrings] count] == 0) 
     return; 

    [self setupControllerForAccessory:connectedEA 
        withProtocolString:[[connectedEA protocolStrings] objectAtIndex:0]]; 
    [self openSession]; 
} 

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode 
{ 
    switch (eventCode) { 
     case NSStreamEventOpenCompleted: 
      // This case always gets called twice, once for input and once for output 
      NSLog(@"stream %@ opened", aStream); 
      break; 
     case NSStreamEventHasBytesAvailable: 
      break; 
     case NSStreamEventHasSpaceAvailable: 
      break; 
     case NSStreamEventErrorOccurred: 
      break; 
     case NSStreamEventEndEncountered: 
      [self closeSession]; 
      break; 
     default: 
      break; 
    } 
} 

- (void)closeSession 
{ 
    [[_session inputStream] close]; 
    [[_session inputStream] removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [[_session inputStream] setDelegate:nil]; 

    [[_session outputStream] close]; 
    [[_session outputStream] removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [[_session outputStream] setDelegate:nil]; 

    _session = nil; 
    _selectedAccessory = nil; 
    _protocolString = nil; 
} 
+0

您是否尝试调度到mainQueue而不是全局? – Putz1103

+0

我也试过dispatch_get_main_queue()。同样的问题发生,有时它连续失败9次,有时连续9次。 – jason

+0

你什么时候尝试在代码中使用这些流?由于它正在发送,您可以在打开完成之前使用这些流。 – Putz1103

我不能添加到您的问题评论(少点!),但我有一些暗示,因为我的团队也面临着这是间歇使用流的同样的问题。 我们向网络团队提出了同样的错误。如果可能,请尝试记录错误,很可能在调试器控制台中出现错误“Stream was unexpected”。这可能会出现,也可能不会出现。

以下是苹果文档中提供的类似代码,它也有相同的问题。 https://developer.apple.com/library/ios/samplecode/SimpleURLConnections/Listings/PostController_m.html#//apple_ref/doc/uid/DTS40009245-PostController_m-DontLinkElementID_12

+0

自从我们切换到另一个蓝牙模块后,这个错误已经停止了。这可能是问题所在?不能100%肯定..谢谢 – jason

+0

@jason,我面临同样的问题。你能让我知道你切换到另一个蓝牙模块吗? – ttotto

+0

@ttotto我正在使用ST的蓝牙模块 – jason