Apple has released the stable version of Xcode 9 recently with loads of new features. The most of the iOS developers are saying Xcode 9 is the best release so far as it has great new features that iOS Developers always wanted. You can read more about the Xcode 9 features here.
We have just migrated our existing XCUITest suite to Xcode 9 and found that unit tests written in XCTest passed but the XCUITests stopped working with the following error.
Main Thread Checker: UI API called on a background thread: -[UIApplication delegate]
PID: 740, TID: 51958, Thread name: (none), Queue name: FIRAnalyticsQueue, QoS: 9
The XCUITests couldn’t launch the proxy test runner app at all and test suite crashed. From the error message its obvious that it’s something related to Firebase SDK and something called Main Thread Checker. Some of you might already fall into this trap or you will be as soon as you migrate to Xcode 9. In this post, we will discuss what is this error is all about and how new Xcode featured Main Thread Checker will help to catch potential bugs in the application.
WTF is Main Thread Checker
Before we dive into an error, we will learn WTF is Main Thread Checker and why Apple introduced this tool as part of Xcode 9. As per the documentation, “Main Thread Checker Detects invalid use of AppKit, UIKit, and other APIs from a background thread.” What does this mean?. An iOS Developer can easily understand this but for others, I will try to explain in the simple language.
There are some Apple frameworks designed to use in the iOS apps only in the main thread, using those frameworks in the background thread is a sin. You probably go to the hell in your next life if you use those frameworks in the background thread. If an iOS engineer uses those frameworks in the background thread, the crazy things will happen like unresponsive UI, visual defects, data corruption, and crashes. In short, using those frameworks in the background thread will f**k your iOS app. Main Thread Checker finds such invalid usage of the frameworks and warns an engineer at runtime, not to do this sin. It detects the culprit so that you can punish them if they don’t fix it. Main Thread Checker is the handy tool to detect bugs in the code as soon as possible. It’s activated by default in the Xcode 9.
About An Error in XCUITest
XCUITest launches the proxy test runner app called XCUIApplication to start the tests in the proxy app. The Main thread checker was active for the XCUITest for the respective scheme. While launching a UI for the app, Main Thread Checker detected that Firebase SDK has used UP APIs in the background thread. There was the issue open on the Github here which was fixed by the Firebase team.
There might be some other third party frameworks that might have same issue e.g Flurry users also reported the same issue on Github here but it’s still not fixed at the time of writing this post.
How to Fix XCUITests?
There are few ways we can fix the issue and get going with XCUITests with Xcode 9.
- We can fix the XCUITests by fixing the issue of invalid usage of iOS framework if the issue is inside the app.
- If the Main Thread Checker detects an issue that’s in the third-part framework like Firebase SDK. We need to get them to fix the issues immediately.
- If the Main Thread Checker detects an issue that’s in the third-part framework and they can’t fix the issue on time, then, unfortunately, we need to disable the Main Thread Checker from the scheme.Go Product > Scheme > Manage Schemes search the Scheme you use for your tests and press Edit… in the left sidebar press Test and then go to Diagnostics and uncheck Main Thread Checker checkbox
Remember, this isn’t the ideal solution, this is the hack that we shouldn’t be putting in our code. We should focus on fixing the issues directly in the code that causing the invalid use of frameworks.
I hope, you will find this post useful when you stuck into the same problem and save few hours of investigation. Have you migrated your XCUITests to Xcode 9? What are your experiences? Let me know in the comment.