So the old way of handling openURL calls in UIKit was to use the following in an AppDelegate:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { ...
Unfortunately the new @main SwiftUI this is redirected to
.onOpenUrl { url in ...
Thus we miss the dictionary OpenURLOptionsKey.sourceApplication which I would like to determine which app called mine, and then can make the appropriate actions as I have a use case that would require limiting certain scheme urls to be used by 3rd party apps and not others.
What's the best practice to do this? I've not been getting anywhere with the documentation, or searching here. It looked like I might have got a lead on it via onContinueUserActivity/NSUserActivityTypeBrowsingWeb but that doesn't get called either.
CodePudding user response:
So I managed to use this in the app delegate:
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
let sceneConfig = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
sceneConfig.delegateClass = SceneDelegate.self
return sceneConfig
}
Which sets this up in the scenedelegate:
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
// get url and sourceApp out of first URLContext here
}
Unfortunately, if the sender of the URL is NOT from your team, you'll get nil in the UIOpenURLContext.sourceApp
So if you're wanting to create RPCs between your teams apps, you're fine. If you want to communicate between apps from different teams, you'll have to figure out some other way to indicate which app it is and then apply your responding policy to that.
CodePudding user response:
As you mentioned, the straightforward for Registering a handler to invoke when the view receives a URL is:
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView().onOpenURL { url in
// ...
}
}
}
}
However, at this point, we are unable to get the "URL Options".
The solution is to register the handler in a way that gives the needed options, by using onContinueUserActivity(_:perform:)
:
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView().onContinueUserActivity(NSUserActivityTypeBrowsingWeb,
perform: handleUserActivity)
}
}
func handleUserActivity(_ userActivity: NSUserActivity) {
let userInfo = userActivity.userInfo
print(userInfo)
}
}
In this case, we can refer to the userInfo of the registered user activity. The activity type in your case should be NSUserActivityTypeBrowsingWeb
.