Update UIWindow var in AppDelegate from another target

119 views Asked by At

A swift iOS app has 3 targets - AppTarget, Main (static lib which contains the entry point i.e. AppDelegate) and Presentation (static lib which contains UI code). AppTarget depends on Main and Presentation. Presentation depends on Main.

Question is, how do I set the UIWindow variable in Main from Presentation?

@main
public class AppDelegate: UIResponder, UIApplicationDelegate {

    // UIWindow view of UIApplicationDelegate protocol
    var window : UIWindow?

    ...

}

I tried two approaches:

Approach1: Directly access the UIWindow variable using the AppDelegate object, but it gives 'Cannot assign to property: 'shared' is a get-only property' error:

UIApplication.shared.delegate?.window = UIWindow() // Error: Cannot assign to property: 'shared' is a get-only property

Approach2: Use an intermediate static variable like:

// In AppDelegate, 
static var keyWindow : UIWindow? = nil

public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
    // Set UIWindow variable to the static instance.
    window = AppDelegate.keyWindow
    
    // Now, instantiating AppDelegate.keyWindow is the same as instantiating window (?).
 
    ...

    return true
}

// Elsewhere, in Presentation,
func CreateWindow() {
        
    window = AppDelegate.keyWindow
        
    AppDelegate.keyWindow = UIWindow()
        
    AppDelegate.keyWindow?.rootViewController = ViewController()
        
    AppDelegate.keyWindow?.makeKeyAndVisible()
        
}

// ViewController has a simple UI
class ViewController: UIViewController {

    override func viewDidLoad() {

        super.viewDidLoad()
        
        view.backgroundColor = .systemGreen
    }
}

This gives me a black screen, meaning, there's no UI...an empty screen. But I expected to see a green screen.

I understand that UI has to be set in the UIWindow variable of the AppDelegate (if you use another UIwindow variable, its contents are not displayed and you'd get an empty black screen), due to its conformance to UIApplicationDelegate protocol.

How can I achieve this elegantly?

Note1: Assume I've opted out of scenes

Note2: Ignore how AppDelegate in Main invokes CreateWindow() in Presentation, but it somehow does.

0

There are 0 answers