Changed Bluetooth initialization on iOS13

In this blog post I will not only stick to technical side of the problem, but I will also put some thoughts on how sometimes in development everything goes wrong. And how to deal with the situation, till you get the solution.

iOS13 was released on September 19th. Quickly after release, on one of the application we got a lot of feedback from end users, especially Bluetooth stack had some problems. Analytics and crash reporting curves started to rise, customer support had more and more work… You get the picture!

iOS13 Bluetooth stack somehow did not work as expected! Unfortunately, we did not noticed this on beta/prerelease release versions of iOS13.

So, I dig in and investigated what was going on!

First, I checked if we put all requirements for iOS13, like new permission key in Info.plist named NSBluetoothAlwaysUsageDescription. Checked, all good! All other iOS Bluetooth prerequisites also looked OK!

Down the rabbit hole!

At first, I followed “Update all development stack to latest versions” mantra! iOS13 (I have been told; and suggested by Apple) requires all the latest tools, SDKs, runtimes, etc…. Wrong, totally wrong!

At the end, I totally fuc**** up my Mac development environment – by installing/switching incompatibility versions of XCode 10 vs. 11, Visual Studio for Mac 2017/2019, incompatibility/problems between different versions of Mono, .Net Core runtimes and SDKs, etc… It was like a chain reaction: one upgrade/change needed other upgrade and so on. All these things were pulling me into the rabbit hole deeper and deeper…

At one point I even upgraded my current Mac operating system from macOS High Sirerra to macOS Mojave. Well, this was the only positive thing – Mojave is much better and nicer then its predecessor. Furthermore, I even start to do (for me) silly things, like: writing Objective-C and debugging some 3rd party libraries.

From my experience (and my feeling), I knew that this is not the right way to go! From my chaotic situation, I just needed to calm down, stabilize the process and go step by step!

On top of everything, customer and end users were also starting to get nervous!

Crazy as hell!

I went back on start, by reverting everything on the beginning!

Go to start and go step by step!

I reverted more or less all things to initial versions, and go back to table, brainstorming. At one point I read in one of the blog post that Bluetooth initialization changed on iOS13 to be more transparent to the end users :). Even more, Bluetooth should be used as late as possible in application startup life-cycle! This got me thinking!

By debugging external 3rd Party code I noticed that in iOS AppDelegate didFinishLaunchingWithOptions (Objective-C) or FinishedLaunching(UIApplication app, NSDictionary options) in Xamarin.iOS event CBCentralManager always returned empty list of Peripheral – strange, because I was pretty sure that on pre-iOS13 versions or on Android (yes, I am cross platform Xamarin.Forms developer:) this Bluetooth manager returned list of peripheral on App Start! On iOS13 this list was always empty.

Lets check!

Long story short: after some investigation I came with this code.

Basically, just some iOS startup diagnostics. I wanted to check Bluetooth status and cbCentralManager peripheral list on different points of the application startup sequence.

The output was interesting:



I spotted the problem: on iOS13 Bluetooth stack is not ready yet at the time of “FinishingLaunching” where our code were making important Bluetooth peripherals loading. Instead, on iOS13, only at cbCentralManager.UpdatedState event Peripheral list was ready to be used. Unfortunately, in our current app this was to late. This was the reason why so much problems on iOS13.

The fix

Simple, I just move Bluetooth peripheral loading/initialization code from FinishedLaunchingevent to cbCentralManager.UpdatedState.


  1. Always think before dig into code, even if the problem looks trivial. This is even more important, if problem looks non-trivial.
  2. Don’t relay that just updating to latest version of software/runtime and hope this will solve the problem.
  3. Observe, pay attention to details!
  4. Be always ahead of official releases!
  5. Avoid Apple products 😀 😀 (joke, to be clear)

Happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.