Universal Links Logo

URL Schemes -Implementation Step Two

This entry is part 6 of 12 in the series Universal Links

In this post, we’ll integrate our URL Scheme into the UIKit Scene Delegate app, and we’ll be editing the SceneAppDelegate.swift file.

Handling Scene Delegate Calls

The Scene handler doesn’t have the simple “one-size-fits-all” method that the App handler does. We’ll need to add methods to catch the app starting for the first time, and also being foregrounded.

Because our implementation is so crazy simple, we don’t care whether or not we were called at start, or from foreground, so we should probably just set up a common URL handler that does the same thing that the App Delegate app has, and call it from each of the Scene Delegate handlers.

In the empty UIWindowSceneDelegate Conformance section, add the following code into the file:

func scene(_: UIScene, openURLContexts inURLContexts: Set<UIOpenURLContext>) {
    for context in inURLContexts {
        var status: AppStatus = .off
        if let statusString = context.url.query(),
           let tempStatus = AppStatus(rawValue: statusString) {
            status = tempStatus
        }
        currentViewController?.updateUI(status: status)
    }
}

Look familiar? It’s pretty much exactly the same method that we added in the last post, but it has been specialized into the scene(_: UIScene, openURLContexts: Set<UIOpenURLContext>) Scene Delegate method.

However…

If you run the Universal-Scene target, and try entering the Scene Delegate URL Scheme calls:

  • iul2://?stop
  • iul2://?caution
  • iul2://?go

You end up with the generic “off state”:

That’s because scene(_: UIScene, openURLContexts: Set<UIOpenURLContext>) is only called at “cold start” time; the first time the app runs. You can test this, by quitting the app from Xcode (or double-homing and swiping off, in the simulator), and try iul2://?stop. You’ll get a red circle:

We’ll need to add one more delegate method, in order to catch URLs when the app is foregrounded: the scene(_ inScene: UIScene, willConnectTo: UISceneSession, options: UIScene.ConnectionOptions) method.

So, just under the scene(_: UIScene, openURLContexts inURLContexts: Set<UIOpenURLContext>) method we just added, add the following:

func scene(_ inScene: UIScene, willConnectTo: UISceneSession, options inConnectionOptions: UIScene.ConnectionOptions) {
    scene(inScene, openURLContexts: inConnectionOptions.urlContexts)
}

This will simply parse out any URLs that have been passed into the app, and call the “cold start” handler.

Now, if you try the URL Scheme calls, they’ll work as expected:

  • iul2://?off
  • iul2://?stop
  • iul2://?caution
  • iul2://?go

This is the release that has the code, up to this point.

At this point, we have the UIKit apps handling URL Schemes correctly. On to SwiftUI…