5

I created a new Storyboard project in Xcode11 and trying to present a ViewController from custom class like this(which works just fine in older project):

let appDelegate = UIApplication.shared.delegate as! AppDelegate
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc : UIViewController = storyboard.instantiateViewController(withIdentifier: "NotificationVC") as UIViewController
appDelegate.window?.makeKeyAndVisible()
appDelegate.window?.rootViewController?.present(vc, animated: true, completion: nil)

Of course this doesn't work now because there is no window variable in AppDelegate anymore which has been moved to the SceneDelegate.

Error: Value of type 'AppDelegate' has no member 'window'

How would you make this code work now?

What I'm trying to do:

I'm trying to show a ViewController when user taps/clicks on the Push Notification Tray.

EDIT: For now I was able to make it work by creating a private static variable in SceneDelegate, and accessing that variable in my custom class:

SceneDelegate.swift

private(set) static var shared: SceneDelegate?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    guard let _ = (scene as? UIWindowScene) else { return }
    Self.shared = self
}

CustomClass.swift

let sceneDeleage = SceneDelegate.shared
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc : UIViewController = storyboard.instantiateViewController(withIdentifier: "NotificationVC") as UIViewController
sceneDeleage?.window?.makeKeyAndVisible()
sceneDeleage?.window?.rootViewController?.present(vc, animated: true, completion: nil)

Which is probably not recommended as stated here: https://stackoverflow.com/a/58547992/9511942, but it works

EDIT2: Here is my another solution thanks to https://stackoverflow.com/a/58557634/9511942

    let window = UIApplication.shared.windows.first
    let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let vc : UIViewController = storyboard.instantiateViewController(withIdentifier: "NotificationVC") as UIViewController
    window?.makeKeyAndVisible()
    window?.rootViewController = vc

If someone finds a better solution, please share.

kironet
  • 766
  • 2
  • 11
  • 27
  • 1
    Check your app delegate file that is there a `var window: UIWindow?` or not – Prashant Tukadiya Oct 25 '19 at 07:25
  • It's not there since new xcode11 projects come with windows variable in scenedelegate. If I add it in appdelegate, my code just does nothing since it's nil and I get `Fatal error: Unexpectedly found nil while unwrapping an Optional value` if I force unwrap `window!` – kironet Oct 25 '19 at 07:26
  • Possible duplicate of [UIApplication.shared.delegate equivalent for SceneDelegate xcode11?](https://stackoverflow.com/questions/56588843/uiapplication-shared-delegate-equivalent-for-scenedelegate-xcode11) – Michcio Oct 25 '19 at 08:21
  • It's actually not a duplicate, I just didn't want to ask 2 questions in 1. The answer from there works in ViewController just fine. But I can't implement it in a custom class. – kironet Oct 25 '19 at 08:31
  • Use the UIApplication.shared.windows property for getting the Application Windows. Please refer https://developer.apple.com/documentation/uikit/uiapplication/1623104-windows – Apparao Mulpuri Oct 25 '19 at 11:24

1 Answers1

2

Use the UIApplication.shared.windows property for getting the Application Windows. Please refer https://developer.apple.com/documentation/uikit/uiapplication/1623104-windows

  • 2
    How does using `UIApplication.shared.windows` solve the issue? An app can have multiple scenes. How would the custom class know which window is the proper window simply by iterating the application windows? – rmaddy Oct 25 '19 at 14:53