Use URL Schemes with SwiftUI

Timo
3 min readMay 23, 2023

In this short tutorial you will learn how to add a custom URL Scheme to your SwiftUI app and navigate to specific views in your app.

Register an URL Scheme

In XCode go to your project settings and select the target to which you want to add the URL Scheme.

Open the Info tab and scroll down until you find the section “URL Types”.

As the identifier you should use your bundle identifier. The URL Schemes can be whatever you want, but make sure it does not collide with predefined URL Schemes that are used for Apple apps. Your app name should be fine.

You can also select an icon for the Scheme, I leave this to you and won’t add it.

The role should be determined and can be Editor or Viewer. According to Apple the difference is following:

Choose a role for your app: either an editor role for URL schemes you define, or a viewer role for schemes your app adopts but doesn’t define.

From: https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app

Handle incoming URLs

SwiftUI comes with a handy little modifier that monitors incoming URLS:

View()
.onOpenURL { url in
// handle the in coming url or call a function
handleURL(url: url)
}

That’s it, with this little addition you can work with your custom URL Scheme.

Handle URL Hosts

To navigate to specific view it makes sense to build URL like this: “myapp://navigate/id”

The “navigate” stands for something like notes, post, etc. The “id” is used to identify a specific post we can navigate to. An example could be something like this: “myapp://posts/2184234”. This example should navigate to a post with the id “2184234”.

To resolve the incoming URL you can access the host of the URL Scheme like this:

private func handleURL(url: URL) {
switch url.host {
case "post":
// change the selected tab from the tabbar
self.selection = 0
default:
break
}
}

In this little example I use my first tab of a Tabbar to be selected when a URL Scheme is monitored that has “post” as its host.

Navigate to specific views

Selecting a tab based on the URL host is pretty cool, but we can even open specific views based by the id we can read from the URL.

In order to achieve this we will use the NavigationStack which was introduced with iOS16.

But before we can navigate, we have to get the id of the post we want to navigate to. Therefore we will use the “onOpenURL” handle again”

PostOverview()
.onOpenURL { url in
handleURL(url: url)
}

To handle the navigation you can use following implementation:

private func handleURL(url: URL) {
switch url.host {
case "post":
self.urlSchemePost = self.posts.first(where: { $0.id?.uuidString == url.pathComponents[1] })
if let post = self.urlSchemePost {
self.urlSchemeNavigation.toggle()
} else {
// Display an error message that the post wasn't found
}
default:
break
}
}

To really navigate we use the “.navigationDestination” modifier:

.navigationDestination(isPresented: self.$urlSchemeNavigation) {
if let post = self.urlSchemePost {
PostView(post: post)
}
}

Testing

You can simply test the URL Scheme by creating a URL an paste it into Safari. You can also paste the URL into Reminders to be able to test different behaviors without pasting it into Safari every time you try to test your Scheme.

Summary

That’s it, you can now navigate to a specific view by using a custom URL Scheme with a few simple steps.

If you liked this story, please let me know.

Additional ressources

--

--

Timo
Timo

Written by Timo

Developing apps for iOS using SwiftUI. Get my lastest app -> https://apps.apple.com/us/app/id1635759048

Responses (1)