NSRunLoop blocks incoming data

Hello,


I try to use the Bluetooth communication synchronously. I send the data to the BTLE device and wait for the response to continue in the same method unless a timeout occurs.

I wanted to use NSRunLoop for the wait. However, I have the problem that only when the loop is completed, the data received in the meantime can be processed. So the loop seems to block the processing of the data.

The data is sent in a separate thread


... create command data
if (![self sendCommand:nd_commandData timeOutMesc:ui_timeOutMSec command:ui_command error:error])
{
    // Timeout
    return false;
}
... continue working with the received data


sending method with timeout:

-(BOOL)sendCommand:(NSData *)nd_sendData timeOutMesc:(uint)ui_timeOutMSec command:(UInt16)ui_command
{
  b_exitConditionSleep = false;
  b_timeOutOccurred = false;

  self.ni_totalResponseLength = 0;
  self.ni_expectedResponseLength = 0;

  // Clear buffer
  memset(&uia_receivedDataBytes[0], 0x00, sizeof(uia_receivedDataBytes));

  [[BTLE_Communicator sharedInstance] setDelegate:self];

  // send data
  [[BTLE_Communicator sharedInstance] sendDataFromAppToBLEDevice:nd_sendData];

  BOOL b_rechTimeOut = true;
  NSDate *start = [NSDate date];
  NSTimeInterval timeInterval;
  uint ui_differenz;
  NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.01];

  while (!b_exitConditionSleep && [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:loopUntil])
  {
    loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.01];

    timeInterval = [start timeIntervalSinceNow] * -1;
    ui_differenz = round(timeInterval * 1000);

    if (ui_differenz >= ui_timeOutMSec) {
        NSLog(@"Command: 0x%hX - Timeout reached: %u", ui_command, ui_differenz);
        b_rechTimeOut = false;
        b_timeOutOccurred = true;
        break;
    }
  }
  return b_rechTimeOut;
}


receiving method:

-(void)communicatorPeripheralDidReceiveResponseUARTData:(NSData *)nd_data
{
  NSLog(@"ResponseUARTData %@", nd_data);


  if (!b_timeOutOccurred)
  {
    b_exitConditionSleep = true;
    [self processResponseData:nd_data];
  }
}


Maybe someone has an indication of what I'm doing wrong.