Instantiating HMHomeManager causes a background thread error - ios

I have a fresh iOS app / project; all I've done is import the HomeKit framework. When I instantiate HMHomeManager:
var homeManager = HMHomeManager()
Xcode yells at me:
Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]
... this occurs even if I wrap it in DispatchQueue.main.async {}
Since this project is effectively blank, I'm assuming this an Xcode bug ... but am I doing something wrong?

Related

iOS app is crashing on ios 13 and with Xcode 11 when it didn't before

Our app is crashing with the fatal exception:
Fatal Exception: NSInternalInconsistencyException
Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.
Our app used to not throw this exception on previous versions of iOS (12 and below) and when I would compile on Xcode 10. Now, on iOS 13.3.1 and compiling on Xcode 11.3.1 our app crashes 10 seconds after opening every time. I looked into this exception and it seems Apple has decided to prevent apps from accessing the UIKit on background threads (please correct me if I'm wrong here). After enabling the Main Thread Checker I was able to pinpoint the line that was causing this crash. Backtracing the code led me to this line:
dispatch_async(dispatch_get_main_queue(), ^{
//Code that uses the StoreKit to retrieve purchase data,
//then updates the UI using UIKit based on this information
});
This code is fine though right? Because even though it's dispatching this block of code, it's doing it to the main thread, so this shouldn't be the issue, correct? Well, even after moving this block of code out of the dispatch_async() function, it still crashes. So then I looked at the singleton for this class, which looks like this:
+(instancetype)sharedPurchaseManager
{
static PurchaseManager * sharedPurchaseManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedPurchaseManager = [[PurchaseManager alloc] _init];
});
return sharedPurchaseManager;
}
And I wondered if the _init() for the PurchaseManager was happening in a background thread. So I tried moving the allocation for PurchaseManager out of the dispatch_once() block and the app stopped crashing. Furthermore, the Main Thread Checker stopped interrupting the program at the line that uses UIKit. I'm pretty sure that moving my _init() code out of the dispatch_once() block is not the correct way to go about fixing my issue, as this is the standard singleton design pattern (please correct me if I'm wrong). So then how should I go about fixing this issue? Furthermore, we have about 10+ crashes in our code that is due to the same exception, and with a similar design pattern to our PurchaseManager, so we would want a solution for all of these exceptions.
It sounds like [[PurchaseManager alloc] _init] contains some UI code, but +(instancetype)sharedPurchaseManager is accessed first time from background thread.
So you can try two approaches:
1) find the way explicitly initialize sharedPurchaseManger on the main thread (eg. in applicationDidFinishLaunching)
2) try to use the following
dispatch_once(&onceToken, ^{
dispatch_sync(dispatch_get_main_queue(), ^{ // << intentionally synchronous!
sharedPurchaseManager = [[PurchaseManager alloc] _init];
}
});

UIApplication delegate must be used from main thread only - Swift

I am getting "runtime: UI API called from background thread: -[UIApplication delegate] must be used from main thread only
" runtime issue for Fabric initialisation line. Not sure how to solve it. Please help
Thanks
Fabric.with([Crashlytics.self,Zendesk.self])
It's because you are trying to access the UI from background thread. Just call the UI change in main thread.
DispatchQueue.main.async {
application.statusBarStyle = UIStatusBarStyle.lightContent
}
UI process are maintained under main thread.

-[GCKCastDeviceProvider stopDiscovery] must be called on main thread

In react native using the google cast sdk 3 everything we reload the app get crash and the error is -[GCKCastDeviceProvider stopDiscovery] must be called on main thread
We put all the code inside:
dispatch_async(dispatch_get_main_queue(), ^{
// my code block
});
We also check if really on the main thread with this:
if ([NSThread isMainThread]) {
NSLog(#"on main thread");
}
Based from this release note, all methods in CastContext that your app calls must be called from the main thread, otherwise an Exception will be thrown. Also, this documentation stated that all SDK methods must be called from the main thread.

-[UIApplication delegate] must be called from main thread only

This warning leads to a serious problem cause I really can't call the delegate outside of the main thread using Xcode 9 beta 2. Strange thing is that this was working when I was using Xcode 8.3.3.
Also I thought it would only be good practice to call delegates from main thread only, isn't it? So why is this causing the app to crash now?
Just call it from the main thread like this.
Objective-C
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication delegate] fooBar];
});
Swift
DispatchQueue.main.async {
YourUIControlMethod()
}
Reaching out to your app delegate like this, is a hint that your architecture could use a little cleanup.
You can call delegates from any thread you want. You only need to make sure you're on the main thread for UIKit calls.
Or that you're on the correct thread your CoreData objects expect. It all depends on the API contract your objects have.
In Swift, you could also use DispatchQueue.main.async to call the UI controlling method from the main thread
DispatchQueue.main.async {
YourUIControlMethod()
}

Changing UI from a background thread

I getting an error that Iam changing the autolayout engine from a background thread , is there's a way to know which block of code makes this warning ? or I just have to search for it by myself ??
Thank you.
Probably there is a better answer but I would start by putting
for Swift:
assert(NSThread.isMainThread(), "Expected code to be called on main thread");
for Objective-C:
NSAssert([NSThread isMainThread], #"Expected code to be called on main thread");
to all sections of your code you're suspicious about.
This way app will crash if you're doing that code not on main thread.
Is this error an error or is it an exception? If it is exception you can try to catch it using exception breakpoint like here: How to debug “Collection was mutated while being enumerated” errors and like, when Xcode does not provide me with enough information? ?
After having looked at your exact message looks like what you need is:
This code PSPDFUIKitMainThreadGuard causes assertions on UIKit access outside the main thread
taken from iOS9 - This application is modifying the autolayout engine from a background thread — where?.

Resources