kCTFontManagerErrorDomain is missing from version of iOS before 9.0
A few weeks ago I was implementing a dynamic font loader for our theming system on iOS. I turned to Core Text and it’s font manager. Being a good citizen I also wrote code to handle any eventual error originating from the font manager at the same time.
I tested the code path and made sure we were handling any errors. For example trying to load the same font multiple times. All was good!
The code was merged into the master branch and our continuous delivery system took over. As with all of our changes a new build is created every hour and sent out for testing. This build contains all changes batched up for the last hour. Which are quite a lot of changes most of the time. Spotify is a large application with many developers.
However it was at this step which people internally began reporting crashes when launching the app 💥 Uh-oh, was that me? 😰
The crash 💥
Unfortunately the crash also looked like a weird one. The app was actually not even launching, but instead the crash happened when iOS tried to load the binary. Odd. It also only happened when trying to open the app on a device running iOS 7 or 8. With iOS 9 the app launched normally. Personally I didn’t get any stack trace containing useful information when debugging it. Luckily another developer got some symbols which lead us to the dynamic font loading I had just created. Yes it was me, doh 😣
After som quick digging and testing, it turned out that the symbol for kCTFontManagerErrorDomain is actually missing from the iOS 7 and 8 SDKs. Even though the symbol was marked as available since iOS 3.2 😣 When iOS loaded the app binary and tried to resolve all the symbols it ran across this little doozy, for which it can’t find a symbol and terminates 💥
The fix ✅
This assumes a deployment target of iOS 8.0 or higher. For iOS 7 compatibility see the note after the code block.
- Run the code under iOS 9 and print the string value of the constant. ✂
- Change all usage of the constant to use this string instead. 📋
- ????
- PROFIT!!! 💰
/**
* Error domain for Core Text’s font manager.
*
* @discussion The real Core Text symbol is missing in iOS 8. Usage
* of the real constant will cause dyld to fail loading the app.
*/
static NSString * const SPTCoreTexFontManagerErrorDomain = ⏎
@"com.apple.CoreText.CTFontManagerErrorDomain";
Update: If you’re still targeting iOS 7 or earlier it’s a bit more involved as you’ll have to use “com.apple.coretext” for iOS 7 users. Creating a function which returns the correct one seems like a reasonable workaround.
The radar 📡
I haven’t filed a radar with Apple about it. As the last versions of iOS 7 and 8 have shipped, a long time ago. We’ll just have to have our own constant defined for this one 😿
I did do some Googling on the issue but it seems no-one else has either ran into this (unlikely). Alternatively no-one has written about it. Hope this helps someone else running into this issue 😅