Hypothesis:
I have a custom URL shortener that redirects to a branch.io long URL.
That custom URL domain is registered in my app's entitlements file for Universal Links.
When a user taps a short link, the app opens and calls application:continueUserActivity:restorationHandler:...
In that method I get the redirect URL (branch) that stands behind the short link, create a new NSUserActivity based on the new link and call "continueUserActivity" method (with the new activity as a parameter) from Branch SDK.
The problem is that the callback from Branch SDK doesn't return anything connected to that link. It returns as if no URL was passed.
If I hardcode the link that comes from redirect and call Branch SDK immediately, without waiting for the redirect response, then everything works fine. I suppose it's something time related in Branch SDK.
The question is: how can I make Branch recognize the link and give me back the params I need when using the redirect scheme described above? (I want to use my own URL shortener, not the one from Branch)
In determining whether a Branch link needs to be handled or not, Branch checks to verify that the NSUserActivity is of type NSUserActivityTypeBrowsingWeb. If it is, Branch checks the .webpageURL to determine if it is a Branch link. If it is not, Branch understands that no Branch link has been clicked.
To manually pass a Branch link into the SDK after the app has been opened some other way there are two functions available: .continue and .handleDeepLink.
.continue
let activity = NSUserActivity(activityType: "NSUserActivityTypeBrowsingWeb")
activity.webpageURL = URL(string: "https://testbed-swift.app.link/77Q527xswy")
Branch.getInstance().continue(activity);
.handleDeepLink
Branch.getInstance().handleDeepLink(URL(string: "https://testbed-swift.app.link/77Q527xswy"))
If you call one of these methods, the Branch SDK will handle the Branch link passed in. If these methods are not working for you, I would check to verify that you are actually passing in a working Branch link in the code and not the shortlink that you are using to open the app.
Related
Let's say I have the following universal link:
https://myapp.test-app.link/yXDv3WQKOA?$uri_redirect_mode=2&product_id=1
as I captured the response of the above request, I can see branch.io will trigger the deep link with the default value of $deeplink_path (from: https://docs.branch.io/links/integrate/#deep-linking)
window.top.location = validateProtocol("myapp://open?link_click_id=71978436528162224363");
my workaround is to override $deeplink_path and duplicate my query params with urlencode, such that:
https://myapp.test-app.link/yXDv3WQKOA?$uri_redirect_mode=2&product_id=1&$deeplink_path=open%3Fproduct_id%3D1
then it can trigger the deep link with query params:
window.top.location = validateProtocol("myapp://open?product_id=1&link_click_id=71978436528162224363")
My workaround works but it looks bad as I have to duplicate the query params, is there any settings on branch.io that I can pass the query params from the universal link to my deep link?
The approach seems to be correct. However, if you want to globally open the app using $uri_redirect_mode=2 then you can set URI Scheme Deep Link Mode as Aggressive Mode in your link settings.
Recommended URI Scheme Deep Link Mode: Intelligent.
This selector allows you to control how and when Branch uses URI schemes to open your app when Universal Links and Android App Links fail. See browser specifics in the docs here.
Conservative mode will never use URI schemes if there is a risk of error messages.
Intelligent mode is recommended, and uses Branch data to safely use URI schemes everywhere, with the slight risk of error messages in certain browsers if the app is uninstalled.
Aggressive will force URI schemes everywhere, causing users without the app to see error messages in some browsers.
If you're creating a link by appending query parameters, just append the control parameters to the URL. Please make sure to URL encode everything, lest the link will break.
Refer to this documentation for more details:
https://docs.branch.io/deep-linking/routing/#option-2-let-branch-use-your-existing-deep-link-routing
In case you have more doubts, please write to support#branch.io.
How can I add deeplink (url like https://www.example.com) in iOS using swift.
The scheme in plist is not working if I enter url in it.
You can check the screenshot of plist attached.
You are attempting to register your app for the URI scheme https which Apple has already reserved for Safari, therefore you will not be able to use it.
Option 1: Custom URI Scheme
You must come up with a custom URI scheme like customURI://www.domain.com
Downside: If a user clicks on this link without the app installed. iOS will show that user and error.
Option 2:Universal Links
Apple launched Universal Links in iOS 9 to enable developers to associate their http link with their app. This requires you to host your own AASA file on your domain so that your domain becomes associated with your app ID.
Option 3: Branch.io
Branch will actually bundle up Universal Links and URI schemes and use them appropriately when necessary. They also perform deferred deep linking. They'll host your AASA file for you, but your app domain will have to be either https://*.app.link or some dedicated subdomain of a domain that you own.
only to be precise:
If you need more docs about in Apple docs, use the CORRECT name for the technology.
If You use url starting with a schema different from http (for example fb:// for FB) is not a LINK, is a "custom" url.
Anyway use: custom url and see at:
https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html
I'm trying to use the callback functionality of the URL schemes for Google Maps on iOS.
The way how to do that is documented here.
However, I did not manage to get this to work. There is no additional symbol showing up as described in the documentation.
Is this actually still possible or has this feature been removed?
Independent of my application, I also tested this by pasting the URL scheme in the Safari browser, but it doesn't work there either.
It simply starts the Google Maps app but apparently ignores the callback parameters.
Edit:
This is the URL from the example of the documentation:
comgooglemaps-x-callback://?center=40.765819,-73.975866&zoom=14
&x-success=sourceapp://?resume=true
&x-source=SourceApp
The only difference would be that the success parameter gets the URL of the app you want to open when the user clicks on the callback button.
Check if your application's url scheme has been implemented correctly and that you're specifying a valid callback url (that directs back to your app).
Some links that might be useful:
https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html
http://iosdevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html
I am implementing firebase dynamic links in my iOS app and I can already parse the link, redirect to AppStore etc. Now I want to distinguish the first run of the app, when user installs it from the dynamic link - I want to skip the intro and show him the content that is expected to be shown.
Is there some parameter, that I could catch in application(_:didFinishLaunchingWithOptions:) so I could say that it was launched thru the dynamic link?
The method application(_:continueUserActivity:userActivity:restorationHandler:) is called later, so the intro is already launched.
This case is difficult to test, because you have to have your app published on the AppStore.
You actually don't need to have the app published in the App Store for this to work — clicking a link, closing the App Store, and then installing an app build through Xcode (or any other beta distribution platform like TestFlight or Fabric) has exactly the same effect.
According to the Firebase docs, the method that is called for the first install is openURL (no, this makes no sense to me either). The continueUserActivity method is for Universal Links, and is only used if the app is already installed when a link is opened.
I am not aware of any way to detect when the app is opening for the first time after install from a 'deferred' link, but you could simply route directly to the shared content (skipping the intro) whenever a deep link is present. If a deep link is NOT present, show the regular intro.
Alternative Option
You could check out Branch.io (full disclosure: I'm on the Branch team). Amongst other things, Branch is a great, free drop-in replacement for Firebase Dynamic Links with a ton of additional functionality. Here is an example of all the parameters Branch returns immediately in didFinishLaunchingWithOptions:
{
"branch_view_enabled" = 0;
"browser_fingerprint_id" = "<null>";
data = "{
\"+is_first_session\":false,
\"+clicked_branch_link\":true,
\"+match_guaranteed\":true,
\"$canonical_identifier\":\"room/OrangeOak\",
\"$exp_date\":0,
\"$identity_id\":\"308073965526600507\",
\"$og_title\":\"Orange Oak\",
\"$one_time_use\":false,
\"$publicly_indexable\":1,
\"room_name\":\"Orange Oak\", // this is a custom param, of which you may have an unlimited number
\"~channel\":\"pasteboard\",
\"~creation_source\":3,
\"~feature\":\"sharing\",
\"~id\":\"319180030632948530\",
\"+click_timestamp\":1477336707,
\"~referring_link\":\"https://branchmaps.app.link/qTLPNAJ0Jx\"
}";
"device_fingerprint_id" = 308073965409112574;
"identity_id" = 308073965526600507;
link = "https://branchmaps.app.link/?%24identity_id=308073965526600507";
"session_id" = 319180164046538734;
}
You can read more about these parameters on the Branch documentation here.
Hmm... as far as I'm aware, there's not really anything you can catch in the application:(_:didFinishLaunchingWithOptions) phase that would let you know the app was being opened by a dynamic link. You're going to have to wait until the continueUserActivity call, as you mentioned.
That said, FIRDynamicLinks.dynamicLinks()?.handleUniversalLink returns a boolean value nearly instantly, so you should be able to take advantage of that to short-circuit your into animation without it being a bad user experience. The callback itself might not happen until several milliseconds later, depending on if it's a shortened dynamic link (which requires a network call) or an expanded one (which doesn't).
I know it's possible to pass data from one app to another app on the same device using custom url schemes or protocol handlers.
Is it possible to pass data from one app to another app that isn't installed? Ideally the user would be taken to the app store for the uninstalled app, the user would download the uninstalled app, and the custom url scheme from the original app would still pass the data to the newly installed app.
Is that possible?
Is it possible to pass data from one app to another app that isn't
installed?
YES.
using the x-callback parameters, we can ask the target app to call us back on our own URLs, even handling success and error scenarios.Sort of like custom HTTP headers, these callback parameters are identified with an x- namespace:
x-error : URL to open if the requested action generates an error in the target app. This URL will be open with at least the parameters “errorCode=code&errorMessage=message. If x-error is not present, and a error occurs, it is assumed the target app will report the failure to the user and remain in the target app.
x-source : The friendly name of the source app calling the action.
x-success : If the action in the target method is intended to return a result to the source app, the x-callback parameter should be included and provide a URL to open to return to the source app. On completion of the action, the target app will open this URL, possibly with additional parameters tacked on to return a result to the source app. If x-success is not provided, it is assumed that the user will stay in the target app on successful completion of the action.