A version of this tip appeared in the documentation I wrote for Views and Controls in SwiftUI.
This modifier has nothing to do with opening URLs for websites. These URLs are solely the ones that can be opened by your app, and your app alone.
onOpenURL modifier is for SwiftUI apps that use the new SwiftUI App lifecycle that does not use AppDelegate or SceneDelegate. If your project has these files in it, you probably won’t be able to get this modifier to work, like I couldn’t. When creating a project, be sure to choose ‘SwiftUI App’ as the Life Cycle option instead of ‘UIKit App Delegate’.
To create a unique URL scheme for your app, select the Info tab of your project settings, whether that be for an iOS or macOS target. Without changing the Custom Target Properties at the top of the screen, you’ll see that there is already a URL types section at the bottom of the screen. Opening this and clicking the ‘+’ button will allow you to create a new URL scheme for your app, providing that it is unique and not the same as any other app on a user’s device. For the purposes of this example I have called it
my-scheme, but you can choose anything.
The Identifier field is optional, but you may want to use it, as the URL type is simply referred to as Untitled in this menu without it.
Now that we have a URL scheme in place, we can do the rest in code. In the example below, I’ve added the ability to use a
TextField to change what link is opened. The URL scheme you set up needs to be set as a constant in the
ContentView struct. If you are using my-scheme as I was, you don’t need to do anything.
You can see here that I’ve created a string constant with what I believe to be every allowed character in a URL.
I’ve also allowed every character to determine whether it is valid for the construction of URLs.
This extension of String provides a computed property that will return a valid URL string. First the string is checked for being empty, and then it is filtered to only include valid URL characters. This string is then checked for its ability to create a URL before being returned. In other words, this computed property can fail a precondition for either being empty or, after being filtered, being invalid for the creation of a URL. This allows us to have confidence that the string can be used to create a URL.
There is also an unfailable intialiser for URL, which will take any String and fail a precondition if it cannot be created from the underlying
Here’s our SwiftUI:
Whether you type a URL or not, the link that says “Open” will open that URL, and the onOpenURL modifier will add that URL to a list. Since we are doing this inside the app that those URLs are opened in, we don’t actually go anywhere. If you want to see a link actually do something, try entering a URL that starts with the URL scheme you set in Safari. This will ask you if you want to open the URL in your app, and then you will be taken back to the app.
If everything is working, the URLs you enter in Safari should also be added to the opened URLs list.