Can someone please help me, Im new to swiftUI and I want to implement universal link for my app. I have prepared my AASA and also added associated domain to the app. But I am confused when it comes to the code in Scene delegate for opening the app when the link is clicked.
This would be the solution with uikit. But how would I do this with swiftUI?
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { return false }
This is what im trying
func scene(_ scene: UIScene, continue userActivity: NSUserActivity)
{
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL,
let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else
{
return
}
if let userActivity = scene.userActivity
{
self.scene(scene, continue: userActivity)
}
}
Related
I am following this tutorial from Firebase to implement Direct Links into my app: Firebase Dynamic Links
My code in my app delegate never seems to run properly. When I run the project I am able to use the link and open the app. But none of the print statements will run so I can't tell if it ran successfully or not:
import UIKit
import Firebase
#main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
return true
}
func handleincomingDynamicLink(_ dynamicLink: DynamicLink) {
guard let url = dynamicLink.url else {
print("Thats weird. My dynamic object link has no url")
return
}
print("Your incoming link parameter is \(url.absoluteString)")
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity,
restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
let handled = DynamicLinks.dynamicLinks()
.handleUniversalLink(userActivity.webpageURL!) { dynamiclink, error in
guard error == nil else {
print("Found an error! \(error!.localizedDescription)")
return
}
if let dynamicLink = dynamiclink {
self.handleincomingDynamicLink(dynamicLink)
}
}
return handled
}
#available(iOS 9.0, *)
func application(_ app: UIApplication, open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
return application(app, open: url,
sourceApplication: options[UIApplication.OpenURLOptionsKey
.sourceApplication] as? String,
annotation: "")
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?,
annotation: Any) -> Bool {
if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
return true
}
return false
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
Xcode gives me this error after I use the link:
[connection] nw_read_request_report [C1] Receive failed with error "Software caused connection abort"
use below delegate method in SceneDelegate Class:
func scene(_ scene: UIScene, continue userActivity: NSUserActivity)
I can't get firebase dynamic links to work on new app installs for a SwiftUI app. Their documentation on step 6 and 7 shows stuff for AppDelegate https://firebase.google.com/docs/dynamic-links/ios/receive?authuser=0
Try 1
I moved it to scene delegate but then it asked me to a add application open url so I did and ended up with this code:
extension AppDelegate {
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
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
print("deeep shit")
return application(app, open: url,sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,annotation: "")
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
print("deeep shit 2")
if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
// Handle the deep link. For example, show the deep-linked content or
// apply a promotional offer to the user's account.
// ...
return true
}
return false
}
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: RootView())
self.window = window
window.makeKeyAndVisible()
}
guard let userActivity = connectionOptions.userActivities.first(where: { $0.webpageURL != nil }) else { return }
print(userActivity)
}
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
print(URLContexts, "URLContexts")
}
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
print(userActivity.webpageURL, userActivity.referrerURL, "sdhagvdgjks")
}
}
RootView()
.onOpenURL(perform: { url in
DynamicLinks.dynamicLinks().handleUniversalLink(url) { dynamicL, error in
if let url = dynamicL?.url {
/// do stuff
}
}
})
Try 2
I skipped Scene Delegate and used the SwiftUI Modfier onContinuesUserActivity https://developer.apple.com/documentation/swiftui/view/oncontinueuseractivity(_:perform:)
extension AppDelegate {
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
return application(app, open: url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String, annotation: "")
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
// Handle the deep link. For example, show the deep-linked content or
return true
}
return false
}
}
RootView()
.onOpenURL(perform: { url in
DynamicLinks.dynamicLinks().handleUniversalLink(url) { dynamicL, error in
if let url = dynamicL?.url {
/// do stuff
}
}
})
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb, perform: { activity in
print(activity.webpageURL, activity.referrerURL, "please work")
})
But then I get this error:
[Firebase/Analytics][I-ACS023001] Deep Link does not contain valid required params. URL params: {
"match_message" = "No pre-install link matched for this device.";
"request_ip_version" = "IP_V6";
}
Could someone please help me out?
Had the same problem as I was trying to implement referrals in my app Whisper Memos. Here's what worked for me:
Go to settings for your target, tab Info.
Find section URL Types
Add URL type with your bundle identifier. Should look something like this:
Your onOpenURL handler will now be called, but with a long URL, such as: tech.median.Whisper://google/link/?deep_link_id=https...
Convert your long URL to DynamicLink instance:
let dynamicLinks = DynamicLinks.dynamicLinks()
if let fromCustom = dynamicLinks.dynamicLink(fromCustomSchemeURL: url) {
deepLinkState.handleLink(link: fromCustom)
return
}
Now you can use this dynamic link to navigate inside your app.
Using Firebase Dynamic Links, I want to be able to click a link to open an iOS app.
The app is under development and is not yet on the AppStore.
I set it while looking at the document, but even if the app is started by clicking the link, the application (_: continue: restorationHandler :) method in AppDelegate is not called.
I set it according to the following procedure. Is something wrong?
Add "pod 'Firebase / DynamicLinks'" to Podfile and install
Open the .xcworkspace file
Create Dynamic Links “https://XXXX.page.link/test”
Access “https://XXXX.page.link/apple-app-site-association”
{"applinks":{"apps":[],"details":[{"appID":"XXXXXXX.[Bundle
ID]","paths":["NOT /_/","/"]}]}}
Create a URL type to use for dynamic links
Enable "Associated Domains" and add "applinks: XXXX.page.link"
Implement AppDelegate as below
import UIKit
import Firebase
import FirebaseDynamicLinks
#UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity,
restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
let handled = DynamicLinks.dynamicLinks().handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
// ...
}
return handled
}
#available(iOS 9.0, *)
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
return application(app, open: url,
sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
annotation: "")
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
// Handle the deep link. For example, show the deep-linked content or
// apply a promotional offer to the user's account.
// ...
return true
}
return false
}
}
I was calling the scene method of SceneDelegate.
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Create the SwiftUI view that provides the window contents.
let rootView = ContentView()
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: rootView)
self.window = window
window.makeKeyAndVisible()
}
guard let userActivity = connectionOptions.userActivities.first(where: { $0.webpageURL != nil }) else { return }
print("url: \(userActivity.webpageURL!)")
}
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
print("url: \(userActivity.webpageURL!)")
}
...
}
Implementation should be in SceneDelgate instead of AppDelegate
I have set up a dynamic link with firebase now I want to know whether the link is clicked or not.
I have already added function:
#available(iOS 9.0, *)
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
return application(app, open: url,
sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
annotation: "")
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
// Handle the deep link. For example, show the deep-linked content or
// apply a promotional offer to the user's account.
// ...
print("dynamic link \(dynamicLink.url)")
return true
}
return false
}
private func application(_ application: UIApplication, continue userActivity: NSUserActivity,
restorationHandler: #escaping ([Any]?) -> Void) -> Bool {
let handled = DynamicLinks.dynamicLinks().handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
print("dynamic link \(dynamiclink?.url)")
}
return handled
//return true
}
I want to know how do I know the link is clicked or not? So that I can open a view for link Click
I'm having an issue with Deep Linking. when I go to safari, In the url i enter myapp:// and press Enter. it redirects me to the app.
However none of the function in the AppDelegate is getting called.
I need to take the parameters from the URL.
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([Any]?) -> Void) -> Bool {
print("Continue User Activity: ")
return true
}
func application(_ application: UIApplication, handleOpen url: URL) -> Bool {
showSimpleAlertView("hahah", message: "adasdasds", withPresneter: self.window!.rootViewController!, withCompletionHandler: nil)
return true
}
As from the online tutorial, on of these 2 function should get called.
I believe that handleOpen function was deprecated in iOS 9... Try this one instead:
func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
I ran into the same issue today. After doing some research I learned there's a new method in iOS 13 that captures the deep linking URs. Within SceneDelegate try this:
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if let deepLinkContext = URLContexts.first {
print("the url \(deepLinkContext.url)")
print("the options \(deepLinkContext.options)")
}
}