ExternalAccessory framework broken on iOS 11

We produce an IAP2 Bluetooth accessory. On the iOS 11 GM, the InputStream provided by the accessory's EASession frequently hangs, rendering our app unusable (we rely on low latency I/O with the accessory). The hangs occur regardless of whether we schedule the stream in a RunLoop or use polling. It appears to be related to the `hasBytesAvailable` property/stream event.


When using RunLoop scheduling, we attempt to read an arbitrary amount of data from the InputStream after consuming the `hasBytesAvailable` stream event. The first read works as expected, then one of the following occurs:

  1. no more `hasBytesAvailable` events are fired
  2. `hasBytesAvailable` only fires again after a seemingly random delay


When polling, we read from the stream while the `hasBytesAvailable` property returns true, spinning otherwise. Similarly to the RunLoop approach, the first read appears to succeed. After the first read, one of the following occurs:

  1. The reader thread is hung trying to acquire an NSRecursiveLock (to access `hasBytesAvailable`)
  2. `hasBytesAvailable` never becomes true


I have confirmed that this issue does not occur on iOS 10.3.3 (the same codebase functions perfectly fine).


I have reached out to Apple via MFi support, DTS, and filed a bug report. Can anyone help?


UPDATE 9/27/17 (1/2):

Apple has taken action on our bug report and did confirm that there was some kind of issue with EA. If anyone else has been in contact with Apple, please share your experience here.


UPDATE 9/27/17 (2/2):

I've just finished some testing with the 11.1 Beta. All the issues remain except one: the Bluetooth connection no longer completely dies. The I/O is still unusable.


UPDATE 10/9/17:
Just finished testing the 11.1 Beta 2 (15B5078e). No improvements.


UPDATE 10/30/17:
Other users here are reporting that this same sort of behavior occurs when using the Lightning connector.

iOS 11.2 Beta improves things, but only slightly. The IAP connection still frequently hangs.

Replies

We are also seeing some nasty problems with iOS 11 lightning accessory support. I raised some of them here:

https://forums.developer.apple.com/message/252801#252801


Another *really* nasty bug we're seeing is that sometimes iOS will go into a spin, constantly outputting the following debug message:


accessoryd(IOAccessoryManager)[162] <Error>: error reading from EA session UUID (null), protocol com.***.yyy


The phone heats up and the battery drains really fast.


I have found the MFi code-level support helpful, so it would be worth contacting them if you can afford to pay for the support incident. However, if the problem is a bug in iOS all they can do is to try to raise the priority with the Apple the EA developers, so if you if you have the time also raise a bug report with Apple.

Have you guys resolve the issue for iOS 11? I am experiecing it on both lighting connector hardware as well as bluetooth hardware that our app supports. When the devce goes to sleep and wakes up, we lost connection to both bluetooth devices or lighting connector hardware.


I added this to Info.plist and it worked


<key>UIBackgroundModes</key>

<array>

<string>external-accessory</string>

</array>

Hi,

We have an iAP bluetooth device, prior to 11.2 we have had issues creating connections on a select number of devices, but with 11.2 beta 3 we have total failure. I am still waiting for Xcode beta to update to further diagnose the issue, but it looks like our EASessions inputstream is either hanging or closing entirely. The app seems to function normally for the first few requests, and then close to socket after some time. I will update once i have had a chance to properly debug this, but at the moment this is total failure of our app rendered by this update.

Update from our end:


When Apple originally took action on initial bug report, they marked it as a duplicate of a previously reported issue. They've since closed the duplicate issue, but have kept my report open. They asked for feedback on 11.2 Beta (which did not fix the issue), and that's the last communication that I've had with them (Nov 8).


The good news is that Apple seems to be working on the problem. The bad news is that this does not appear to be a particularly high priority.


Anyone who is observing issues with ExternalAccessory, please take the time to submit your own bug reports to Apple. If you're feeling especially helpful, mirror your reports on Open Radar.


Bug Reporter: https://bugreport.apple.com/web/
Open Radar: https://openradar.appspot.com/page/1

iOS 11 completely breaks Bluetooth classic iAP data transfer when app is in background.


  • Reproduced on devices running iOS 11.03, 11.02, 11.2 ( 15C5107a )
  • iOS 10.3.2 works fine


Updating our MFI external accesories over Bluetooth Classic ( using a BlueGiga module in our MFI external accessory ) takes up to 25 minutes. The connection fails if user presses home button and app is suspended to background for more than a second or two.

On iOS 10.3.2, the app can be in background for the entire 25 minutes and everything works fine.


Background execution was reliable prior to iOS11. I can run same code on an iOS 10 device and background works fine.


<key>UIBackgroundModes</key>

<array>

<string>external-accessory</string>

</array>

<key>UISupportedExternalAccessoryProtocols</key>

<array>

<string>com.mycompany.btclassicdevice</string>

</array>


In debugger on iOS 11 device I can see interactive packets continue to be sent for maybe 2 - 3 seconds after pressing home button.

If I run in debugger on a device with iOS 10.3.2 iPad Mini MGNR2LL/A, it kepps goinf for 25 minutes with app in background.


I created a bug report with Apple today, 35593708

iOS 11 completely breaks Bluetooth ( Classic ) MFI External Accessory background mode



We have a few field reports of people on beta 2 or 3 not able to authenticate a Lightning device that worked fine before. We cannot replicate it, so it is some marginal behavior.


We have been shipping this for a long time. The basic MFI design has existed since iOS 5 and 30 pin with an upgrade to the Lightning module. This is the first time we have run into this issue.


Beta 3 is close to shipping, so we are a bit worried.

We've been using BT 2.0 on MFI since iOS5, its been fairly rocksolid the whole way. iOS11 and in particular iOS 11.2 beta 2 and 3 have absolutely killed it. If the beta releases in this state it will be terrible for all MFI products.

Hi


I have just installed iOS 11.2 Beta 5 and it appears that we are also still seeing one of the issue reported above of " EAAccessoryManager sharedAccessoryManager not returning any accessories even though the accessory is connected" . More specifically when we use "count" to access the number of items on the list of returned accessories it always appears to be 0 even though the device is connected.


If our observations are indeed the case then its hard to believe that this is close to final release as surely this has major potential impacts on all apps accessing Bluetooth devices.

Two weeks ago I reported a new bug 35593708 "iOS 11 completely breaks Bluetooth ( Classic ) MFI External Accessory background mode."


Apple’s response:


Engineering has determined that your bug report (35593708) is a duplicate of 34680928 and will be closed.


I wish I could view 34680928and see if any work is being done on this.

Thanks for raising this... I'm experiencing the same behavior. Just so maybe we can as a community align do folks see any consistent behavior in their hangs? In my case it's very consistent regardless of polling or event handling reads... I'll get 14 blocks of 2036bytes from our device and then the same behavior you've seen. Guess my question is for others it's it random for you or repeatable behavior? Thanks again

Anyone seeing improvement or worsening in the public release of 11.2?

No change I can see. Backgrounding the app without the background external accessory flag set simply causes the streams to be closed when the app returns to the foreground.

Hi,

We use a lightning connector attached external accessory that also have 100% fail on iOS11.2 (but ok on 11.0)

We use two EA sessions to communicate with a smart card reader. One channel works fine, but the other simply times out when we try send data.

ATS connected between iPhone/iPad and accessory shows no data on failing channel.

I've just submitted a new bug

35943132 Using multiple ExternalAccessory sessions fails on iOS11.2

We also device rolled to thousands of end users. Hopefully we managed to stop the majority of upgrading to 11.2 but quite a lot have already reported the issue back to us.

Best regards,

Håkan

We also encountered the same problem

We send data with External Accessory Framework via Lightning port, but we find (by looking at the ATS report) that all bytes data had been already change to 0x00 when they output Lightning port .

Although the all bytes data is changed to 0x00, the length of the data received by the external device is correct which is consistent with the data sent by the app.

The app receives all the data sent from the external device and the data is correct.

This issue only appears on iOS 11.2, iOS 11.1 and previous system do not have this issue.


UPDATE 12/15/17:

Just finished testing the 11.2.1 and 11.2.5 Beta (15D5037e). No improvements.


UPDATE 01/16/18:

This issue be fixed on iOS 11.2.5 beta 4 build 15D5054a.

We did submit a bug report on this a ways back. The issue where our App loses Bluetooth connectivity when in the background appears to be resolved with IOS 11.2.1! That's the good/great news. However, we now appear to be having issues pairing cleanly with many IOS devices (iOS believes the pairing completes cleanly, but our device did not complete). We'll be working this as a separate issue.