Dynamic Links Firebase on App Install SwiftUI - swift

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.

Related

Unable to navigate to other view controller after Google sign-in

How can I go to another view controller after successfully signing with google? I've tried "self.inputViewController?.performSegue(withIdentifier: "goToMain", sender: self)" in my App Delegate but not getting any respond. Am I supposed to add the method in App Delegate or the view controller with the sign-in button?
App Delegate
import UIKit
import Firebase
import GoogleSignIn
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate{
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GIDSignIn.sharedInstance()?.clientID = "my_client_id"
GIDSignIn.sharedInstance()?.delegate = self
return true
}
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
if let error = error {
print(error)
return
}
guard
let authentication = user?.authentication,
let idToken = authentication.idToken
else {
return
}
let credential = GoogleAuthProvider.credential(withIDToken: idToken,
accessToken: authentication.accessToken)
Auth.auth().signIn(with: credential) { authResult, error in
if let error = error {
let authError = error as NSError
print(authError.localizedDescription)
return
}
self.inputViewController?.performSegue(withIdentifier: "goToMain", sender: self)
}
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return GIDSignIn.sharedInstance().handle(url)
}
// 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.
}
}
Are you sure about the inputViewController is not nil? This may a reason for not working.
You can add a function to test this, or you can use the print function to check, or, you can use debug point to check inputViewController is nil or not.
I'd like to add comment but I don't have enough reputation point :).
Good luck.

Can't get Firebase Dynamic Link

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)

Detecting Source Application for Launch Depracated? Aternatives?

I am trying to detect if another application has launched my app in order to launch a different view to accept a pdf being passed to it. It appears that LaunchOptionsKey can be used in the AppDelegate, but the following code dosn't seem to work. Can anyone tell me if I'm using the code wrong or if there are alternatives. Most references use the sourceApplication to do this, but I read claims that is was depracated in 2019, yet apple still has it in their documentation? Also I notice that switching launch views only works in the SceneDelegate instead of the AppDelegate. Apparently this is also a recent change?
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
print("finished launching")
if launchOptions?[UIApplication.LaunchOptionsKey.sourceApplication] != nil {
print("Launched by another app")
startVC = "addFile"
} else {
print("source app not identified")
}
return true
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
print("Scene: finished launching")
//self.window = UIWindow(frame: UIScreen.main.bounds) // black sreen
let storyBoard = UIStoryboard.init(name: "Main", bundle: nil)
if startVC == "addFile" {
let initialVc = storyBoard.instantiateViewController(withIdentifier: "addFile") as! addFileViewController
self.window?.rootViewController = initialVc
self.window?.makeKeyAndVisible()
}
if startVC == "home" {
let initialVc = storyBoard.instantiateViewController(withIdentifier: "home") as! FirstController
self.window?.rootViewController = initialVc
self.window?.makeKeyAndVisible()
}
guard let _ = (scene as? UIWindowScene) else { return }
}

Universal links in SwiftUI

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)
}
}

Clicking the Firebase dynamic link does not call the application (_: continue: restorationHandler :) method in AppDelegate

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