Minimum iOS version is 13, Scene delegate file is completely deleted, only using appdelegate. But open url, continue userActivity and openURLContexts methods are not calling in when app opened using deep link.
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
print("app opened using deep link from \(sourceApplication)")
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "DeepLink"), object: nil, userInfo: nil)
return true
}
func application(_ application: UIApplication, continue userActivity:
NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
print("app opened using deep link ")
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "DeepLink"), object: nil, userInfo: nil)
return true
}
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if let url = URLContexts.first?.url{
print(url)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "DeepLink"), object: nil, userInfo: nil)
}
}
Edit - 1
Invalid redeclaration of 'application(_:open:options:)'
Here is a Sample App I created to test deep links in minimum iOS 13 without SceneDelegate
This is because you might be using wrong open URL method to receive deep links:
The correct one is:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
print("Deep link received \(url)")
return true
}
continue userActivity is generally called in the case of universal links
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
}
So, AppDelegate looks like:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
print("Deep link received \(url)")
return true
}
}
And in Info.plist make sure to add URL Schemes.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string></string>
<key>CFBundleURLSchemes</key>
<array>
<string>deepLinks</string>
</array>
</dict>
</array>
It looks something like this:
Then to test your deep links, go to your browser and write your uri scheme with ://
Example in this case:
deepLinks://mydeeplinkurl
It will ask you to open your app.
And you will get a call back in open URL method
Related
I using Universal linking in my application.
When the user pick on link directly move into root view controller.
But I want to change the rootviewcontroller when user entering through Universal link.
please help to those delegates methods.
There is 2 delegate method that will fire when application is open from link or user tap link as per below.
Swift
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
// handler for URL Scheme "This will called for URL schema"
return true
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
// handler for Universal Links "This will called for Universal Link"
return true
}
Use this delegate method:
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: #escaping ([Any]?) -> Void) -> Bool
I have successfully integrated Firebase dynamic links and when I click on dynamic link then my app is opening.
The issues I'm facing is after opening app from dynamic links, continue userActivity: method should be called, but nothing happens.
I've checked the all the possible thing but didn't recognised the issue.
I've searched the SO for this but none of the answer helped me.
My Code:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
GIDSignIn.sharedInstance().clientID = kGoogleSignInClientId
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
// DynamicLinks.performDiagnostics(completion: nil)
FirebaseApp.configure()
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
if url.absoluteString.contains(kFBAppId) {
return FBSDKApplicationDelegate.sharedInstance().application(app, open: url, options: options)
}
if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
print(dynamicLink.url ?? URL(string: "test") as Any)
return true
}
return GIDSignIn.sharedInstance().handle(url, sourceApplication: options[.sourceApplication] as? String, annotation: options[.annotation])
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
//This method is not getting called
}
Additional answer for those using separate SceneDelegate.swift apart from AppDelegate.swift:
This method in AppDelegate >
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if userActivity.activityType == CSSearchableItemActionType {
}
is now in SceneDelegate >
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
}
I don't know whether they keep their doc. up to date or not.
I have just copy-pasted the code from the Google's official Firebase dynamic link document.
Why was the continue userActivity: method is not called?
The reason is (See the difference in following method)
Copy pasted from google doc. - Wrong one
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
}
I wrote this (without copy paste from google doc.) - Correct one
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([Any]?) -> Void) -> Bool {
}
I've made bold the difference.
This is what I was trying for many hours. It is really very frustrating for me to blindly trust on google doc.:-|
Hope this may help other.
You need to check two times.
When app. is running in the background and is opening from Link:
Delegate method is:func checkForTransferedTicket(_ userActivity: NSUserActivity) { }
When app. is NOT running in background and is opening from Link:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,options connectionOptions: UIScene.ConnectionOptions) { if let userActivity = connectionOptions.userActivities.first {
print(userActivity)
}
}
I've set up universal links with the Branch SDK. The links are opening the app correctly, and application:continueUserActivity:restorationHandler: is called, but not `application:openURL:options:'
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
Branch.getInstance().application(app, open: url, options: options)
return true
}
The deprecated application:openURL:sourceApplications:annotation is also not called. didFinishLaunchingWithOptions and willFinishLaunchingWithOptions both return true.
What could possibly causing openURL to not be called when the app opens from tapping a universal link?
Clay from Branch here.
The application:openURL:sourceApplications:annotation function (now deprecate to application(_:open:options:)) is actually only called in response to the old Apple Linking system of standard URI schemes.
Universal links are actually handled within the application(_:continue:restorationHandler:) function.
// Respond to URI scheme links
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
// pass the url to the handle deep link call
Branch.getInstance().application(app, open: url, options: options)
// do other deep link routing for the Facebook SDK, Pinterest SDK, etc
return true
}
// Respond to Universal Links
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([Any]?) -> Void) -> Bool {
// pass the url to the handle deep link call
Branch.getInstance().continue(userActivity)
return true
}
Your deep link handling should mostly be dealt with in your handler callback:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let branch: Branch = Branch.getInstance()
branch?.initSession(launchOptions: launchOptions, deepLinkHandler: { params, error in
if error == nil {
// params are the deep linked params associated with the link that the user clicked -> was re-directed to this app
print("params: %#", params.description)
}
})
return true
}
I working on Universal links implementation for our iOS app.
Here is my small piece of AppDelegate:
private func application(_ application: UIApplication, openURL url: URL, sourceApplication: String?, annotation: AnyObject) -> Bool {
DeepLinkHelpers.handleUniversalLink(url.absoluteString)
return true
}
private func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
DeepLinkHelpers.handleUniversalLink(userActivity.webpageURL?.absoluteString)
return true
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
signalRConnector.launch()
NotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.processRestartSignalRNotification(_:)), name: NSNotification.Name(rawValue: "restartSignalR"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.reachabilityChanged(_:)),
name: ReachabilityChangedNotification,
object: reachability)
do {
try reachability.startNotifier()
} catch {
Logger.save(text: "Unable to start notifier")
}
return true
}
I have processed all other steps for universal links integration:
Published apple-app-site-association file in our Web application
Switched on Associated domains feature on developers.apple.com
Specified associated domains in xcode
Checked Target Membership for entitlements file
Said xcode to wait until app will be started manually (instead of
autostart)
I doing following to debug:
Connecting ipad
Starting project in xcode
In ipad opening Calendar and click on link contained in some event.
Link has following format: app.domain.com/#/123456789
Ipad opens app but continueUserActivity not calling and i can't
handle code from the url for navigate to exact state within an app.
According documentation continueUserActivity should be executed. It is not executing both when app is running in background and when app not running.
Thank you in advance! Any help appreciated.
As of iOS 12, Swift 4.2, and Xcode 10 Apple has again changed method signature (type of restorationHandler) to
func application(_ application: UIApplication, continue userActivity:
NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
I suspect this is because you've marked the continueUserActivity function as private. I've never seen that, and in fact Swift 3 actually gives an error when I try. There don't appear to be any examples of code structured that way on all of GitHub.
I'd suggest removing the private scope.
after ios 13 you should use ScenDelegate:
//when app is running
func scene(_ scene: UIScene, continue userActivity: NSUserActivity)
//when app is not running
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
In 2019, this is what helped me (from this guide: https://medium.com/#abhimuralidharan/universal-links-in-ios-79c4ee038272 ):
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([Any]?) -> Void) -> Bool {
print("Continue User Activity called: ")
if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
let url = userActivity.webpageURL!
print(url.absoluteString)
//handle url and open whatever page you want to open.
}
return true
}
I have successfully implemented deep linking with Branck iOS SDK.
However on re-opening application shows following warning in console:
Attempting to load the view of a view controller while it is
deallocating is not allowed and may result in undefined behavior
(UIAlertController: 0x16b00800)
My AppDelegate with basic code implementation is:
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
// Branch initialization
let branch: Branch = Branch.getInstance()
branch.initSessionWithLaunchOptions(launchOptions, andRegisterDeepLinkHandler:
{ optParams, error in
if error == nil, let params = optParams
{
print("Branch params: ", params.description)
}
})
return true
}
// Respond to URI scheme links
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool
{
print("Branch url URI: ", url)
// pass the url to the handle deep link call
Branch.getInstance().handleDeepLink(url)
return true
}
// Respond to Universal Links
func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool
{
print("Branch universal link ")
Branch.getInstance().continueUserActivity(userActivity)
return true
}
}
How to remove above warning?
To remove warning AppDelegate must additionally implement application:willContinueUserActivityWithType function that will return true
func application(application: UIApplication, willContinueUserActivityWithType userActivityType: String) -> Bool
{
return true
}