iOS App Delegate params dictionary doesn't contain any relevant links - ios

I've added the Branch.io SDK to my iOS project. I have a custom URL scheme which works fine, I've added universal app links which work fine.
Now, I've enabled in my Dashboard the iOS app where I've added my custom URL scheme, custom URL for downloading the app, the App Prefix and the bundle identifier.
In the 'quick links' section I've created a quick link witch has a ["key": "value"] pair for the deep link section and added a redirect again to my jenkins where the ipa can be downloaded.
Now, if I access that link by copy/pasting in mobile safari, without the app installed i'm correctly taken to Jenkins.
At this point I run the app from xcode, and in app delegate I have
branch = Branch.getInstance()
branch.initSession(launchOptions: launchOptions, andRegisterDeepLinkHandler: {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
// params will be empty if no data found
// ... insert custom logic here ...
print("params: %#", params as? [String: AnyObject] ?? {})
} else {
print(error?.localizedDescription ?? "")
}
})
The issue is here that params always only contains two params:
params: %# ["+clicked_branch_link": 0, "+is_first_session": 0]
I've also implemented
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
let branchHandled = branch.application(application,
open: url,
sourceApplication: sourceApplication,
annotation: annotation
)
if (!branchHandled) {
// If not handled by Branch, do other deep link routing for the Facebook SDK, Pinterest SDK, etc
var handled = false
handled = //this is Facebook handling
guard handled == false else { return true }
} else {
// do some stuff if it's coming from branch
}
return branchHandled
}
My interest is for branch to pass my ["key": "value"] pair in order to have it handled like a deep link at this point, but I don't know what else to try.

The failure of deferred deep-linking could be due to mismatch of Branch key and Branch link for a particular Branch app. Verify the Branch link used for deferred deep-linking is generated using the same Branch key which is used in info.plist of the iOS project.

Related

How to NOT handle some Universal Links programmatically?

My iOS application handles universal links to redirect safari users to my app. So far everything is working great, if a user tap a link to my web site from Google my app is opening instead of my web site like this:
from safari https://my-web-site.com -> my-app
But my app doesn't implement certains features that my web site does, so I would like to programmatically reject some URLs and let my users on safari instead of redirecting him in my app, like this:
from safari https://my-web-site.com -> my-app
OR
from safari https://my-web-site.com?reject -> safari
That should by possible according to Apple documentation:
It’s important to understand that if your app uses openURL: to open a universal link to your website, the link does not open in your app. In this scenario, iOS recognizes that the call originates from your app and therefore should not be handled as a universal link by your app.
Unfortunately that's not what's appending, instead of staying in safari, my user is redirected to my app for a brief moment, then redirected again to safari like this:
from safari https://my-web-site.com?reject -> my-app (briefly) -> safari
here is my code for AppDelegate.swift:
internal func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard let url = userActivity.webpageURL else { return false }
guard let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true) else { return false }
let params = urlComponents.queryItems ?? []
if params.contains(where: { $0.name == "reject" }) {
// This line should prevent the app from opening according to Apple's documentation
application.open(url)
return false
} else {
return true
}
}
So anyone have an idea how I could make the rejection of an Universal link the way it's described by Apple's documentation ?
note: the rejection of an universal link need to be done programmatically by the app, according to data stored locally. So adding a path exception in the apple-app-site-association file is not an option in my case :
{
"applinks": {
"apps": [],
"details": [
{
"appID": "XXXXXXXXX.com.my-app",
"paths": [
"*",
"NOT /reject"
]
}
]
}
}
If you prefix an entry in the paths array with "NOT" then you can explicitly prevent a match. So in your example you could do something like
["NOT /settings/*", "NOT /activity/*", "/*"]
which would prevent paths with /settings or /activity prefixes, and then match everything else.
Reference

branch io clicked_branch_link is false

I have integrated branch.io deep linking in my iOS app (Swift 4.2). What I want is canonical_url when user taps on branch.io short link.
When app is running in background I get all required parameters in following block. but when app is not running and try to tap branch.io short link then app launches but I do not get required parameters even clicked_branch_link is false.
Branch.getInstance().initSession(launchOptions: launchOptions)
{ (params, error) in
print(params as? [String: AnyObject] ?? {})
guard error == nil else { return }
guard let userDidClick = params?["+clicked_branch_link"] as? Bool else { return }
}
Please make sure you have all the basic implementation code as shown in our docs here: https://branchmetrics.github.io/docs/pages/apps/ios/#initialize-branch.
In addition, you can find a working implementation of the Swift Branch SDK in our Testbed application here: https://github.com/BranchMetrics/ios-branch-deep-linking/tree/master/Branch-TestBed-Swift.

Opening an app from another app - "This app is not allowed to query for scheme"

I am unable to find a clear, precise guide on how to open another custom app from my current custom app.
I keep getting this error:
This app is not allowed to query for scheme myScheme.
I managed to get this working by doing the following:
In the below example the master app is the main app where I want to click a button and open another app. The other app in this example is called app2.
Both of the apps must belong to the same scheme to prevent the above "not allowed" error.
In the below example the scheme is called myapps but it can be anything you set it to in the Info tab (explained below).
In app2:
Click on your app Target (click your app name in the the heirarchy on the left then click your app name under TARGETS).
Click Info tab and scroll down to URL Types.
Click the arrow to expand URL Types, click the + to add a new entry.
Enter a unique identifier in the identifier field (I just used the bundle ID for that app... e.g com.mycompany.app2.
In the URL Schemes field, enter a name for your URL Scheme. In this example we shall call it myapps so we enter myapps into the field. This scheme name will need to be setup in the master app. For each additional app you want to open you need to setup a different scheme name and then also add the scheme name into the master app.
In the master app:
Repeat steps 1 to 5 - the only change will be step 4 as the unique identifier will be different and step 5 if you are setting up multiple apps.
Setup a button.
Connect the button to an action like below:
#IBAction func pressOpenAnotherApp(_ sender: Any) {
openApp(appURL: "myapps://com.companyname.app2"
}
Setup the openApp function:
func openApp(appURL: String) {
let openApp = URL(string: appURL)!
if UIApplication.shared.canOpenURL(appURL) {
UIApplication.shared.open(appURL, options: [:], completionHandler: { (success) in
print("Open App: \(appURL)")
print("Status: \(success)")
})
}
}
This worked for me, although the information is just through my own trial and error so it may not be 100% accurate but it works!
Are you using canOpenURL before attempting to actually open the URL? (You ought to in case the second app isn’t installed.) The documentation goes into plenty of detail, about the requirement of including LSApplicationQueriesSchemes in your Info.plist.
You have 2 App to test this issue.
App_B (App open from App_A)
App_A (App start direct open to App_B)
Step : App_B
Choose set schemes Url in App_B (name you want to redirect open for check this App_B is installed)
Ok We set schemes Url complete.
then go to your App_A (your current App)
Step: App_A
1.create your project
2.create func open schemes url
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
openApp_B_installed()
}
func openApp_B_installed(){
//LSApplicationQueriesSchemes in your Info.plist.
let appName = "App_B"
let appScheme = "\(appName)://"
let appUrl = URL(string: appScheme)
if let url = appUrl,
UIApplication.shared.canOpenURL(url) {
print("App installed")
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: {
(success) in
if (success)
{
print("OPENED \(url): \(success)")
}
else
{
print("FAILED to open \(url)")
}
})
} else {
// Fallback on earlier versions
UIApplication.shared.openURL(url)
}
}else {
print("App not installed")
}
}
add LSApplicationQueriesSchemes in info plist.
enter image description here
Congratulation you done.
You try to test by install App_A , App_B and install App_A only you can debug in openApp_B_installed()
I hope it helps clarify and resolve the issue for this topic.
Thank you

Open URL from button action in Swift

In my app I am retrieving an URL from a parse.com Object.
I want to open the device's browser and show the URL received from Parse when the user clicks on the button.
This is the action:
#IBAction func botonNuevos(sender: AnyObject) {
let query = PFQuery(className: "datos_contacto")
query.getObjectInBackgroundWithId("H52ZxGm3U8", block: {
(questionObject: PFObject?, error: NSError?) -> Void in
let webNuevos: AnyObject! = questionObject!.valueForKey("dato_contacto")
print(webNuevos) //= http://www.touchemotors.com
if let webCallURL = NSURL(string: webNuevos as! String ) {
let application = UIApplication.sharedApplication()
if application.canOpenURL(webCallURL) {
application.openURL(webCallURL)
}
else{
print("failed")
}
}
})
}
when the button is clicked, the log shows the received URL, but the browser is not launched and any error is shown.
Please tell what is wrong in my code. Thank you
UPDATE
Finally after discussion with OP it turned out that value returned by questionObject!.objectForKey("dato_contacto") had whitespace at the end so NSUrl(string:) did not parse it well.
UPDATE
You are using wrong method NSObject.valueForKey(). Use PFObject.objectForKey() instead.
For iOS 9:
From here:
If your app is linked on or after iOS 9.0, you must declare the URL
schemes you want to pass to this method. Do this by using the
LSApplicationQueriesSchemes array in your Xcode project’s Info.plist
file. For each URL scheme you want your app to use with this method,
add it as a string in this array.
If your (iOS 9.0 or later) app calls this method using a scheme you
have not declared, the method returns false, whether or not an
appropriate app for the scheme is installed on the device.
Add http scheme to LSApplicationQueriesSchemes array in Info.plist.

How to enable "Install" or "Open" Button in facebook messenger in a "yet-to-launch" ios App for Testing

I have an iOS app under development [Not yet launched]
And i want to get the following "Open" button visible on it while sharing the "from my app" via facebook messenger using FBSDKMessengerSharer:
Facebook SDK
What i have done is the following:
As per Facebook's guidelines for Optimized integration.
https://developers.facebook.com/docs/messenger/ios#optimized_integration
I have put .plist entries for facebook app ids, my own app id, URL schemes etc.
i confirm the when i type my scheme://, it open up my app.
Facebook developer console on developer.facebook.com has correct entries for the app/bundle.
I have added myself and another user as test users as per the guidelines and Facebook have clearly written this is testable without submitting the app.
And then i have the following pieces of code for sharing in the app:
func Share(){
let image : UIImage = UIImage(named: "Sample")!
let opts : FBSDKMessengerShareOptions = FBSDKMessengerShareOptions()
opts.contextOverride = cContext
FBSDKMessengerSharer.shareImage(image, withOptions: opts)
}
And the following for enabling optimized sharing in AppDelegate:
func application(app: UIApplication,
openURL url: NSURL,
options: [String : AnyObject]) -> Bool {
print("Called OpenURL")
let h = FBSDKMessengerURLHandler()
let a = "com.appcompany-new.name"
if h.canOpenURL(NSURL(string: "temp://abc.xyz"), sourceApplication: a) {
h.openURL(NSURL(string: "temp://abc.xyz"), sourceApplication: a)
}
return true
}
func messengerURLHandler(messengerURLHandler : FBSDKMessengerURLHandler,didHandleOpenFromComposerWithContext context : FBSDKMessengerURLHandlerOpenFromComposerContext) {
cContext = context
print("Called Open from composer")
}
I donot see any button, the Open, Install or Reply button even now. What am i missing?

Resources