Blocking stream operation stopped working on iOS6.1

Background:

My project is a software library that allows its user to access a proprietary 30 pin accessory. The library uses NSInput/OutputStream as part of using the External Accessory framework.


The library has to use NSStream in two ways to access the external accessory (These two ways are part of the public API provided by the library, and I would rather not change it if possible):

(1) Asynchronous read (reading data asynchronously coming from the accessory). This is accomplished by scheduling the input stream on a run loop and setting a delegate to handle stream events.

(2) A blocking write, follow by a blocking read with timeout (sending to accessory a command and getting from it a response). This is presented to the library client as a method with signature "(NSData*) sendCommandAndReadResponse:(NSData*) cmd". Blocking IO is used because typically there is negligible IO latency and a blocking IO interface is much easier for client to use.


To perform (2), the blocking write-read, the library does the following:

-First, [NSOutputStream write:maxLength:] is used for writing

-Then the input stream delegate is temporarily set to nil to temporarily disable the part of the library that does asynchronous read.

-Then [NSInputStream hasBytesAvailable] and [NSInputStream read:maxLength:] are used for polled-based blocking read with timeout.

-Then input stream delegate is restored


Problem:

The blocking write-read worked fine since iOS 4, but has a problem when iOS was updated to 6.1. On iOS 6.1, when performing two blocking write-read in the same UI event, the second write cannot be performed because the output stream reports no space is available.


-If only one blocking write-read is performed in a UI event, or, if two blocking write-read are made in different UI event, it still works.

-There does not seem to be changes to NSStream or External Accessory in iOS 6.1 from the class reference


Question:

-what could be causing the problem in iOS 6.1?

-is the above method of using both asynchronous write/ synchronous write-read the proper way?


Any help is appreciated. Thanks!

iOS 6.1

Posted on Feb 5, 2013 12:33 PM

Reply
Question marked as ⚠️ Top-ranking reply

Posted on Feb 6, 2013 12:26 PM

I had the same problem, are you scheduling your runloop off the UI thread? I was scheduling it on a BG thread and it wasn't getting the events after updating to iOS 6.1. Once I changed it to scheulde it on the main thread, it started getting the notifications.


I change this:


[[_sessioninputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];


to this :

[[_sessioninputStream] scheduleInRunLoop:[NSRunLoopmainRunLoop] forMode:NSDefaultRunLoopMode];


hope this helps

5 replies
Sort By: 
Question marked as ⚠️ Top-ranking reply

Feb 6, 2013 12:26 PM in response to ID Tech

I had the same problem, are you scheduling your runloop off the UI thread? I was scheduling it on a BG thread and it wasn't getting the events after updating to iOS 6.1. Once I changed it to scheulde it on the main thread, it started getting the notifications.


I change this:


[[_sessioninputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];


to this :

[[_sessioninputStream] scheduleInRunLoop:[NSRunLoopmainRunLoop] forMode:NSDefaultRunLoopMode];


hope this helps

Reply

Feb 6, 2013 6:23 PM in response to ovidiufrommundelein

Thanks very much for the suggestion ovidiu.


I scheduled the streams on the main UI thread (by calling [NSRunLoop currentRunLoop] while on main thread) and experienced the problem I posted.


However, if I schedule the streams on a background runloop, writing to output stream actually starts working.


I posted a seperate question about how to start a run loop:

https://discussions.apple.com/thread/4783730

Reply

Feb 8, 2013 1:56 AM in response to ID Tech

I am also using same same method [NSOutputStream write:maxLength:].

My application was working well until i upgraded to IOS 6.1.


I am getting exception :

"ERROR - /SourceCache/ExternalAccessory/ExternalAccessory-213/EAOutputStream.m:-[EAOutpu tStream write:maxLength:] - 230 failed to write because stream does not have space available". when i try to access the above function.


I have tried the change


[[_sessioninputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];


to this :

[[_sessioninputStream] scheduleInRunLoop:[NSRunLoopmainRunLoop] forMode:NSDefaultRunLoopMode];


Still getting the same error message.

Reply

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Blocking stream operation stopped working on iOS6.1

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.