How can I get a url from a universal link? - ios

I usually use the delegate method below when I clicking the universal link to open the app from an inactive/background state; however, it isn't called from a non-running/dead state so I can't use the NSUserActivity object, which provides me the Universal link url I need.
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: #escaping ([Any]?) -> Void) -> Bool {
If you are aware of another solution, delegate method, or anything else that may help me get the url please let me know.
Thank you.

Through this delegate method I receive the universal link in app delegate. Please try it. It may helps you.
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
}

Related

Universal links not working correctly in IOS App - Not opening the correct page

I have an IOS App that requires a member login. I've set up a separate page for new members to log in. When I email them to confirm their new account, I want the link in the email to go to the login page in the app, which is "newlogin.php'. While testing this with Safari on my iPhone and iPad, I have tried almost everything to get this to work, but the link keeps going to the home page in the app, which is mydomain.com.
In the Associated Domains section of Xcode, I entered: applinks:mydomain.com.
Here is my apple-app-site-association file, which is in both the root directory and the .well-known directory:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.com.-mydomain.MyDomain",
"paths": ["/newlogin.php"]
}
]
}
}
And here is the function for the AppDelagate file that I have been struggling with for several days:
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
{
// ?????????????????????????????????
}
At this point, I have no clue what to put in the function where the question marks (???) are entered, in order to make this go to domain.com/newlogin.php. Please, someone help me. I've been at this for several days, and it's starting to get to me. Thank you very much in advance.
First you will check what is the activity type where you will know you are coming from web or not.
Then get url from where you come and do necessary actions based on url.
Check below code.
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: #escaping ([UIUserActivityRestoring]?
) -> Void) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
let url = userActivity.webpageURL!
print("The url : " ,url)
// now do what you want with url
check if url contains .login.php, take user to login page in your app.
}
return false
}
Assuming you're not using SceneDelegate's, You need to register both delegate functions in your AppDelegate.swift file.:
// MARK: - URL
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard let incomingURL = userActivity.webpageURL else { return false }
// Do something with `incomingURL`
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
// Do something with `url`
return true
}

iOS Universal Linking is not Working in swift

I having the Universal linking in my application.
I place my Association file code into the server with the help of backend
Please find My URL: https://www.furnitureinfashion.net/apple-app-site-association/
Whenever I check the domain validation here: https://branch.io/resources/aasa-validator/?domain=https:%2F%2Fdevapp.meet2talk.com#resultsbox
It will show everything is fine, but when I pick on my base URL in safari it cants working.
Anyone suggest to me how do we resolve this issue.
I write the following delegate method in AppDelegate
private func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: #escaping ([Any]?) -> Void) -> Bool
{
if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
let url = userActivity.webpageURL!
let userurl = url.absoluteString
print(userurl)
}
return true
}
Here I add the App Capabilities also.
Capabilities

How to know user is coming into app by using of Universal links

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

iOS, Universal links, Swift. continueUserActivity not calling

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
}

continueUserActivity not called from search closed app

I am trying to use core spotlight to open a view controller from the spotlight search results.
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray *restorableObjects))restorationHandler
{
if(self.window.rootViewController){
[self.window.rootViewController restoreUserActivityState:userActivity];
}
return YES;
}
This seems to work when the app is already running in background, however when it is closed and I tap on the spotlight search result it seems that this method gets not called and the behavior I get is that my application simply starts in the main interface.
Do you have any suggestion for making it work also when my app is closed?
Is there a way to debug what is happening (since I need to run the app to get the debugger attached I don't know how to simulate the app opening from the search result)?.
Niko,
first of all: there's a way to start your app from Xcode and not opening it immediately: open your scheme properties, go to the "run" section, and under "info", there's a switch that will help you to debug what's happening:
"Wait for executable to be launched".
If you activate this switch, you can launch the app from Xcode, Xcode will wait until the app is opened from search and then it will attach the debugger to it.
Hope that helps!
Ivan
In the new Swift 5 there is a new new file called SceneDelegate.swift.
Use the method scene(_ scene: UIScene, continue userActivity: NSUserActivity)
If you are using the Facebook SDK, and in didfinishlaunching your are returning FBSDK, instead of plain text, and returning true at the end, it can cause problems hitting continueuseractivity.
After searching a lot, and trying different ways, I just had to
return true and comment this:
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
didFinishLaunchingWithOptions needs to return YES so continueUserActivity will be called.
Add to End of application: didFinishLaunchingWithOptions:
NSDictionary *activityDictionary = launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey];
if (activityDictionary) {
NSUserActivity *userActivity = activityDictionary[UIApplicationLaunchOptionsUserActivityTypeKey];
if (userActivity) {
return YES;
}
}
return NO;
continue userActivity is changed in the latest swift version. Changing the func worked for me.
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([Any]?) -> Void) -> Bool
to
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool.
If the app was closed, application: continueUserActivity: is not called. Instead, you get all the information launchOptions dictionnary in application: didFinishLaunchingWithOptions:
// In application: didFinishLaunchingWithOptions:
NSDictionary *activityDic = [launchOptions objectForKey:UIApplicationLaunchOptionsUserActivityDictionaryKey];
if (activityDic) {
// Continue activity here
}
If your app uses Scenes, make sure you have implemented both delegates:
this one for the case when the app is not running at the moment of clicking the link:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// the url is expected to be in connectionOptions.userActivities.first?.webpageURL in case if its type is NSUserActivityTypeBrowsingWeb
}
AND this one for the case when the app is in background or in foreground:
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
// the url is going to be in userActivity.webpageURL
}
If your app does NOT use Scenes:
Double-check this method call carefully, because it has changed some time ago and legacy projects can still have old code:
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: #escaping ([Any]?) -> Void) -> Bool
This is the call which worked in my case:
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
(Don't be deceived by Xcode's warning suggesting to add private - it won't help)
Check Apple's documentation about Universal Links for more details.
Here it follows the complete answer following your advices.
// In application: didFinishLaunchingWithOptions:
NSDictionary *activityDic = [launchOptions objectForKey:UIApplicationLaunchOptionsUserActivityDictionaryKey];
if (activityDic) {
if(self.window.rootViewController){
NSUserActivity * userActivity = [activityDic valueForKey:#"UIApplicationLaunchOptionsUserActivityKey"];
[self.window.rootViewController restoreUserActivityState:userActivity];
}
}

Resources