This question relates to both ios (swift) and android.
I'm working on building the backend implementation for a banner system that our mobile apps need to integrate with. Some of the banners need to redirect a user to a section of the app when pressed.
What is the best practice for triggering route navigation based on data returned in an API call?
For example, a list of banner objects in JSON where a key references the page to navigate to - would deep linking apply here, does it make sense for the apps to create a mapping of routes that I can reference by passing a string?
I feel like there has to be a simple solution here but the mobile team I'm working with seems pretty adamant.
In my current project (iOS), we are using deep links to map navigation to a certain tab of our app. So you could send it through JSON and then post a Notification, which your main controller is listening to (TabBarController for example), and then select the wanted index to go to, or any other navigation logic you need.
// Registering the deeplink with DeepLinkKit pod (https://github.com/button/DeepLinkKit)
self.router?.register("a/created/path") { link in
if let link = link {
debugPrint("Router: \(String(describing: link.url))")
NotificationCenter.default.post(
name: Notification.Name(Configuration.App.kGoToSomewhere),
object: nil
)
}
}
Or just extracted from your JSON and then setup the notification
call { URL in
NotificationCenter.default.post(
name: Notification.Name("ANotification"),
object: nil
)
}
And then in your main controller
class MainTabBarController: UITabBarController {
func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(selectTab),
name: Notification.Name("ANotificaton"),
object: nil
)
}
}
func selectTab() {
// Do your navigation logic here
}
I hope it helps!
Related
I have added flutter to a native iOS code. I have UIButton and on pressing this button, I am presenting a FlutterViewController. I have been following this.
Here's my code for presenting the FlutterViewController:
#objc
#IBAction func openProfile() {
print("open profile")
lazy var flutterEngine = FlutterEngine(name: "patient_profile_engine")
flutterEngine.run(withEntrypoint: "", libraryURI: "");
let profileVC =
FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
present(profileVC, animated: true, completion: nil)
}
This code is working fine and the flutter view is opening and since I haven't specified and entry point yet so it using the main.dart.
The problem is that I need to pass some information to the Flutter dart code. e.g. a dictionary ["patient_id": "123456"] during the initialization.
I will have to do the same in Android native Java code as well.
Is there any easy way?
You will probably want to write a platform channel to communicate between the native code and the flutter engine.
An alternative, for this purpose, would be to use runWithEntrypoint:initialRoute: method to start the engine, encode the data into the initial route, and parse it on the flutter side.
I'd like for users to be able to share a link (e.g. app.com/SKFLA - this is primarily because deep links on their own aren't clickable) via Facebook etc. When clicked, this redirects to a deep link app://SKFLA. If the app is installed, this opens the app - this is all working fine so far. But if the app isn't installed, I'd like to open the app store on the relevant page. Is this achievable? Thanks!
You need UNIVERSAL LINKS
Please check
IOS https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html
Android
https://developer.android.com/training/app-links/
It might also require some extra server-side setup.
Not sure about native behavior.
We used third-party service like https://branch.io/deepviews/.
There is a bunch of similar services.
If someone is still stuck in this issue and needs easiest solution, you will love node-deeplink
1.) If app is installed: Calling an app through deep linking will always call componentDidMount of root component. So you can attach a listener there. Like:
Linking.getInitialURL()
.then(url => {
if (url) {
this.handleOpenURL({ url });
}
})
.catch(console.error);
Linking.addEventListener('url', this.handleOpenURL);
handleOpenURL(event) {
if (event) {
console.log('event = ', event);
const url = event.url;
const route = url.replace(/.*?:\/\//g, '');
console.log('route = ', route);
if(route.match(/\/([^\/]+)\/?$/)) {
const id = route.match(/\/([^\/]+)\/?$/)[1];
const routeName = route.split('/')[0];
if (routeName === 'privatealbum') {
Actions.privateAlbum({ albumId: id });
}
}
}
}
2.) If app is not installed: Just set up a route in your server and node-deeplink package will handle the bridging between web browser to app store when a app is not installed in your mobile.
By this, both the cases will be handled without any struggle
I am wondering if it is possible to send out a URL link to download and install an app from the IOS or Android app store and have the app open to a particular page. IE pass the data somehow from the URL the app during install.
Thanks
Do you know about Firebase Dynamic Links? I think it is exactly what you are searching for, see here: https://firebase.google.com/docs/dynamic-links/
Try branch SDK. Please follow this link
https://dev.branch.io/getting-started/sdk-integration-guide/guide/android/
I realise that I answered something else than was asked, but I'll leave the answer if by some odd case someone will be able to use my answer.
For iOS:
First you must register your custom URL scheme. I can recommend following this tutorial.
A for handling the incoming URL there might be a better way, but I simply implement func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool in AppDelegate.swift and then do a string split (or whatever fits the URL you're expecting), and construct my navigation stack according.
Ex:
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
if let navigationController = self.window?.rootViewController as? UINavigationController {
if url.absoluteString.contains("/messages") {
let myIntroViewController = navigationController!.storyboard!.instantiateViewControllerWithIdentifier("Intro") as! IntroViewController
let messagesViewController = navigationController!.storyboard!.instantiateViewControllerWithIdentifier("Messages") as! MessagesViewController
navigationController.viewControllers = [myIntroViewController, messagesViewController]
}
...
}
}
I'm working on a Xamarin Forms application. It has an Entry field for the visit code on the initial page. I need to extend its functionality so that the application will open when a custom url scheme myscheme://visitcode is encountered, and the Entry will have its Text value prepopulated with the value of visitcode.
I've had success with getting the application to launch.
I added my scheme to the info.plist file in my iOS project, and it properly launches the app when I click on my custom url scheme in Safari on an iPhone.
I added the following line above my MainActivity in my Droid project:
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, DataScheme = "myscheme")]
It properly launches the app when I click on my custom url scheme in Chrome on an Android phone.
The only remaining obstacle is to retrieve the value and populate the Entry field with it.
Can someone help me?
Note: I haven't tested this yet, so make sure your app lifecycle and the place where you handle the events are matching the Xamarin.Forms app lifecycle. That is, make sure Xamarin.Forms.Application.Current is not null. If it is, reshuffle your code to work around that.
For iOS, you have to override OpenUrl in your AppDelegate.cs:
public override bool OpenUrl (UIApplication application, NSUrl url, string sourceApplication, NSObject annotation);
and in Android, you handle that in your MainActivity.cs, in your OnCreate or any other method used as entry point:
var intent = Intent;
var uri = intent.Data;
That should allow you to retrieve the parameters of the url.
You then can retrieve the current Xamarin.Forms Application object, by doing:
var myapp = Xamarin.Forms.Application.Current as MyApplication;
Now, it's up to you to retrieve the right entry, or it's view model, or a service or whatever to connect the dots.
There is a component within the Xamarin store that handles this for you:
http://components.xamarin.com/view/rivets
This will remove the lengthy code requirements in building native implementations.
I'm able to start the application, using the custom URL Scheme
Start My App
The application lunches as usual, but i did need the key user_token=12345. I had less experience with this framework, so don't get any work around. Need help.
Secondly, Can i pass multiple keys using the Custom Schema ?
You need the Android WebIntent Plugin for this.
You can send multiple key
Start My App
Use this as like
document.addEventListener("deviceready", GetCustomUrl, false);
Then the function would be
function GetCustomUrl() {
window.plugins.webintent.getUri(function(url) {
if(url !== "") {
// Here you need to first split with "?" then later with "&"
var link = url.split("?");
var keysPair = link[1].split("&");
// use as per your need
}
});
}
You can check the plugin site for more details.