In WidgetKit
, I am using widgetURL
to construct a custom URL schema, so that I can launch the main app via deep link.
I am trying to handle a custom URL scheme (widget://
) in SceneDelegate
, by launching a view controller from a root view controller.
Here's my code of launching a view controller from a root view controller.
private func handleIncomingURL(_ url: URL) {
if let scheme = url.scheme, scheme == "widget" {
if let rootViewController = self.window?.rootViewController {
// https://stackoverflow.com/questions/33520899/single-function-to-dismiss-all-open-view-controllers
// Dismiss all previous launched VC except root view controller.
rootViewController.dismiss(animated: false, completion: nil)
let greenViewController = GreenViewController.instanceFromMainStoryBoard()
rootViewController.present(greenViewController, animated: true)
} else {
print("no rootViewController")
}
}
}
There are 2 use cases when handling custom URL scheme.
- Previous app is still in app stack. Previous app is restored from the app stack.
- The app is not found in app stack. New app is launched.
Previous app is still in app stack
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
// Called on existing scenes
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if let url = URLContexts.first?.url {
handleIncomingURL(url)
}
}
}
The app is not found in app stack
// Called on new scenes
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
if let url = connectionOptions.urlContexts.first?.url {
handleIncomingURL(url)
}
}
Thing works well when previous app is still in app stack. rootViewController
is not nil, scene(_:openURLContexts:)
is called and our greenViewController
can launched without issue.
However, when the app is not found in app stack, scene(_:willConnectTo:)
is called and rootViewController
is nil. Hence, we are not able to launch our greenViewController
.
May I know, what is the appropriate action to launch a view controller, in scene(_:willConnectTo:)
when root controller is nil?