Dynamic Links Firebase only work the first time - swift

I am adding the Firebase Dynamic Links in my iOS App. I made the configuration according to the documentation and until this point, all right.
When testing, I noticed that the link opens the app and calls the method:
application (_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]
And works!
But when I click the link (dynamic link) again, it just opens the app and does not call the method.
Can someone help me?
My code:
private func application(_ application: UIApplication, continue userActivity: NSUserActivity,
restorationHandler: #escaping ([Any]?) -> Void) -> Bool {
let handled = DynamicLinks.dynamicLinks().handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
// let vc = NomeStoryboard.instance.configuracoes.instantiateViewController(withIdentifier: "idSB_ConfiguracoesApp_Onboard") as! ConfiguracoesAppPageViewController
// UIApplication.shared.keyWindow?.rootViewController = vc
}
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
}
}

Make sure didFinishLaunchingWithOptions returns true.
Looks like you have a slightly older version of continueUserActivity -- maybe try the more modern signature:
func application(_ application: UIApplication, continue userActivity: NSUserActivity,
restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool

Related

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)

SDKApplicationDelegate Use of unresolved identifier

I have two pods installed for facebook login
pod 'FacebookCore'
pod 'FacebookLogin'
than imported FacebookCore in appdelegate. still it shows use of unresolved identifier error.
I have also implemented tags in info.plist
<array>
<string>fb---------</string>
</array>
<key>FacebookAppID</key>
<string>-----------</string>
<key>FacebookDisplayName</key>
<string>-----------</string>
Still not able to get SDKApplicationDelegate.
func application(_ app: UIApplication, open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
if SDKApplicationDelegate.shared.application(app, open: url, options: options) {
return true
}
return false
}
Its because SDKApplicationDelegate is changed to ApplicationDelegate
func application(_ app: UIApplication, open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
if ApplicationDelegate.shared.application(app, open: url, options: options) {
return true
}
return false
}
One more thing to do
class AppDelegate: UIResponder, UIApplicationDelegate
Also import these two pods
import FBSDKCoreKit
import FBSDKLoginKit
Details
Xcode Version 10.3 (10G8)
Swift 5
FacebookCore (0.7.0)
Solution
just replace SDKApplicationDelegate with ApplicationDelegate
Code
import FacebookCore
//....
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
//....
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
guard let urlScheme = url.scheme else { return false }
if urlScheme.hasPrefix("fb") {
return ApplicationDelegate.shared.application(app, open: url, options: options)
}
return true
}
To be able to have facebook login add these 2 methods
func application(_ app: UIApplication,open url: URL,options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool{
if #available(iOS 9.0, *) {
let sourceApplication: String? = options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String
return FBSDKApplicationDelegate.sharedInstance().application(app, open: url,sourceApplication: sourceApplication, annotation: nil)
}
return true
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, open: url as URL?, sourceApplication: sourceApplication, annotation: annotation)
}
import FBSDKCoreKit
import FBSDKLoginKit

How to implement GoogleSignIn

Some of the docs 1 2 say I must use the application:openURL:options:. My question is -- since I'm already using that method, and the sample code for how to implement hijacks it entirely:
func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any])
-> Bool {
return GIDSignIn.sharedInstance().handle(url,
sourceApplication:options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
annotation: [:])
}
How can I identify that the openURL call is for signin?
What I would rather is to implement that method equivalent to how it is in FirebaseUI3:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
let sourceApplication = options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String?
if FUIAuth.defaultAuthUI()?.handleOpen(url, sourceApplication: sourceApplication) ?? false {
return true
}
// other URL handling goes here.
return false
}
As you might have noticed that GIDSignIn.sharedInstance().handle method returns a bool, so you can call it like this:
func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any])
-> Bool {
if GIDSignIn.sharedInstance().handle(url, sourceApplication:options[.sourceApplication] as? String, annotation: [:]) {
return true
}
return false
}
This approach is more useful in case your app supports other different kinds of logins (facebook, twitter etc.)
In that case, all you have to do is to add more if conditions for each kind of urls.
Hope this helps
Actually you don'y have to , you can chain them with || like this
public func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, open: url as URL?, sourceApplication: sourceApplication, annotation: annotation)
|| GIDSignIn.sharedInstance().handle(url, sourceApplication: sourceApplication,annotation: annotation)
|| FUIAuth.defaultAuthUI()?.handleOpen(url, sourceApplication: sourceApplication) ?? false
}
Anyone will hit will return true otherwise if all false then result will be false
According to the docs this method returns YES if GIDSignIn handled this URL.
So it seems that you can do exactly as what you do in the FUIAuth example, i.e. add an 'if' check on the return value:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
let isSignInHandled = GIDSignIn.sharedInstance().handle(url,
sourceApplication:options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
annotation: [:])
if isSignInHandled {
return true
}
// ... other code
}

I have implemented Dynamic link setup now when the link is clicked i want land the app into new page.How can i check link clicked or not?

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

iOS Deep Link doesn't call any function from the AppDelegate

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