Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I refactor my code to call AppDelegate on the main thread?

I recently started migrating my project from Swift3/Xcode8 to Swift4/Xcode9. My app crashes at runtime because the main thread sanitizer allows access to UIApplication.shared.delegate only on the main thread, resulting in a crash at startup. I have the following code, which worked fine in Swift 3 -

static var appDelegate: AppDelegate {
    return UIApplication.shared.delegate as! AppDelegate;
}

Other classes in my code make access to appDelegate. I need to figure out a way to return UIApplication.shared.delegate from the main thread.

Note: Using an DispatchQueue.main.async{} block from wherever access is made to appDelegate is not an option. Need to use it only within the static var appDelegate declaration only.

Looking for a clever workaround.

Relevant crash message:

Main Thread Checker: UI API called on a background thread: -[UIApplication delegate] PID: 1094, TID: 30824, Thread name: (none), Queue name: NSOperationQueue 0x60400043c540 (QOS: UNSPECIFIED), QoS: 0

like image 665
entropy.maximum Avatar asked Aug 23 '17 06:08

entropy.maximum


2 Answers

Solved by using Dispatch Groups.

static var realDelegate: AppDelegate?;

static var appDelegate: AppDelegate {
    if Thread.isMainThread{
        return UIApplication.shared.delegate as! AppDelegate;
    }
    let dg = DispatchGroup();
    dg.enter()
    DispatchQueue.main.async{
        realDelegate = UIApplication.shared.delegate as? AppDelegate;
        dg.leave();
    }
    dg.wait();
    return realDelegate!;
}

and call it somewhere else for

let appDelegate = AppDelegate(). realDelegate!
like image 180
entropy.maximum Avatar answered Oct 14 '22 04:10

entropy.maximum


I use the following:

static var shared: AppDelegate? {
        if Thread.isMainThread {
            return UIApplication.shared.delegate as? AppDelegate
        }

        var appDelegate: AppDelegate?
        DispatchQueue.main.sync {
            appDelegate = UIApplication.shared.delegate as? AppDelegate
        }
        return appDelegate
    }
like image 25
Debaprio B Avatar answered Oct 14 '22 04:10

Debaprio B