Focusmark

Firebase Dynamic Links with SwiftUI (app lifecycle)

3 min read

Introducing onOpenURL

Firebase documentation about Dynamic Links has pretty outdated and misleading instructions.

They use AppDelegate methods such as application:openURL:options: and application:continueUserActivity:restorationHandler:.

If you’re using SwiftUI app lifecycle, these methods won’t even be called. Instead, you’re expected to implement SceneDelegate, which is super complicated and not documented by Firebase.

Luckily, SwiftUI now offers much simpler way to handle URLs. It’s a simple handler called onOpenURL, and it’s used like this:

return WindowGroup {
    ContentView()
        .onOpenURL(perform: { url in
            print("You tried to open (url) !")
        }
    }

This works perfectly with your regular links. However, if user has just installed the app, this method won’t be called.

How to test cold installation

To test the scenario of app not being installed, follow these steps:

  1. Delete app from your device
  2. Open the dynamic link and let it redirect you to the App Store
  3. If your app is not in the App Store yet, don’t worry - this should still work
  4. Build and run app form Xcode
  5. It should now ask you to allow pasting URL. Allow it.

Now your onOpenURL handler should be called.

If onOpenURL isn’t being called

The URL we’re trying to open looks like this: tech.median.Whisper://google/link/?deep_link_id=https...

As I tried to implement it, I kept seeing error that said Failed to open URL.

Turns out, I was missing URL Types in my project configuration:

After adding that, my onOpenURL was being called.

Handling the custom scheme URL

Still, I couldn’t convert this URL into a DynamicLink using the standard code:

DynamicLinks.dynamicLinks().handleUniversalLink(url) { link, error in
    // ...
}

To fix this, you have to call dynamicLink(fromCustomSchemeURL:). My implementation now looks something like this:

if let fromCustom = dynamicLinks.dynamicLink(fromCustomSchemeURL: url) {
    // handle link
    return
}

dynamicLinks.handleUniversalLink(url) { link, error in
    // handle link
}

Focusmark

I'm Vojtech, a software engineer who keeps looking for ways to be more focused in work and life. I'm building FocusTask and Whisper Memos.