title: How do I implement a timeout / wait for an NSStream to effectively make method synchronous
body: <p>I have an input stream and output stream for a bluetooth connected accessory</p>
  
  <p>I want to achieve the following:</p>
  
  <p>write data to outputStream
  wait until data received on inputStream OR until 10 seconds pass
  if inputStream data arrived return data
  else return nil</p>
  
  <p>I tried to implement this like so:</p>
  
  <pre><code>- (APDUResponse *)sendCommandAndWaitForResponse:(NSData *)request {
    APDUResponse * result;
    if (!deviceIsBusy &amp;&amp; request != Nil) {
      deviceIsBusy = YES;
      timedOut = NO;
      responseReceived = NO;
      if ([[mySes outputStream] hasSpaceAvailable]) {
        [NSThread detachNewThreadSelector:@selector(startTimeout) toTarget:self withObject:nil];
        [[mySes outputStream] write:[request bytes] maxLength:[request length]];
        while (!timedOut &amp;&amp; !responseReceived) {
          sleep(2);
          NSLog(@"tick");
        }
        if (responseReceived &amp;&amp; response !=nil) {
          result = response;
          response = nil;
        }
        [myTimer invalidate];
        myTimer = nil;
      }
    }
    deviceIsBusy = NO;
    return result;
  }
  
  - (void) startTimeout {
    NSLog(@"start Timeout");
    myTimer = [NSTimer timerWithTimeInterval:10.0 target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];
  }
  
  - (void)timerFireMethod:(NSTimer *)timer {
    NSLog(@"fired");
    timedOut = YES;
  }
  
  - (void)stream:(NSStream*)stream handleEvent:(NSStreamEvent)streamEvent
  {
    switch (streamEvent)
    {
      case NSStreamEventHasBytesAvailable:
        // Process the incoming stream data.
        if(stream == [mySes inputStream])
        {
          uint8_t buf[1024];
          unsigned int len = 0;
          len = [[mySes inputStream] read:buf maxLength:1024];
          if(len) {
            _data = [[NSMutableData alloc] init];
            [_data appendBytes:(const void *)buf length:len];
            NSLog(@"Response: %@", [_data description]);
            response = [[APDUResponse alloc] initWithData:_data];
            responseReceived = YES;
          } else {
            NSLog(@"no buffer!");
          }
        }
        break;
       ... //code not relevant 
    }
  }
  </code></pre>
  
  <p>So the theory was to have an NSTimer running on a separate thread that would set a boolean when it fired, then also have the handleEvent delegate method set another boolean if data is received. 
  In the method we have a while loop with a sleep that will cease when one of these bools is set.</p>
  
  <p>The problem I am having is that in the 'timeout scenario' my timerFireMethod is not getting called. My gut feeling is that I am not actually correctly setting the timer on a separate thread.</p>
  
  <p>Can anyone see what is going wrong here or suggest a better implementation for the requirement above?</p>