Launching an app from within another app, from a mail link or from a link in a web page can be a very useful feature.
Social networks use this function a lot. However, all apps which have some “sharing” feature can benefit from it.
How to implement the URL schemes in Xamarin? We have to use two different methods for Android and iOS.
This is the task at hand:
– We have an app called superduperapp that should be opened whenever, on a user’s device, a URL as “superduperapp://my_code_is_here” is clicked by the user on their iPhone or Android phone (or: opened by another app on the same device);
– The data following the URL “protocol” (the string “my_code_is_here” in this example) is read by the app, which creates its data context based on that code.
This is one of those times in which Xamarin iOS and Xamarin Android implementations have little in common, since we’re touching the foundations of how the device operating system communicates and deals with the apps.
Xamarin for iOS URL Schemes:
As a first thing, we have to “decorate” the iOS app with the new URL scheme. We do this in the Info.plist file.
Xamarin Studio has a good editor for this file. You have to go to the “advanced tab” and add a “URL Type”. The URL scheme should contain the URL type you want to link your application to. In our case, since we would like superduperapp to be opened by URLs as “superduperapp://my_code_is_here”, our URL scheme will be “superduperapp”.
The “role” field is apparently ignored by iOS, but it’s supposed to mean:
Editor=app can read and write the type of files individuated by the URL
Viewer=can only view that file type;
None=cannot use it (I guess this option is used when an app is updated and we want to delete the file association)
As a second thing, we have to override the OpenUrl method of the Application delegate class:
public override bool OpenUrl (UIApplication application, NSUrl url,
string sourceApplication, NSObject annotation)
/* now store the url somewhere in the app’s context. The url is in the url NSUrl object. The data is in url.Host if the link as a scheme as superduperapp://something_interesting */
That’s it. If you store the url data in a persistent object, you can then use it in your ViewControllers. It is not very elegant, but it could be just sufficient to grab the code passed to the app with the “Host” property of the url, like this:
PersistantClass.CodeEntered=url.Host; //PersistantClass would be your custom class to hold data
To test, we create a web page with a link as this:
which visually translates into this:
When we click on the link on the simulator, the iOS app opens (well, of course we must have installed it first). The app delegate reads the URL in the OpenUrl overridden method. Later, we display – as a test – the code extracted from the link:
The application name does NOT have to be the same of the URL scheme. You can register your app “uncommonApp” to deal with any URL: BeautifulThings://, http:// (if you’re making a browser), whatever://
Xamarin for Android
In Android, the procedure to register an app to deal with a type of URL is (you figured that out already) completely different from that of iOS. We have to work on the AndroidManifest.xml file (contained in the /properties folder).
A typical AndroidManifest.xml file will look like a bit this (depending on the permissions and features the app needs):
<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android” android:versionCode=”1″ android:versionName=”1.0″ package=”superduperapp.superduperapp”>
<uses-sdk android:minSdkVersion=”19″ android:targetSdkVersion=”19″ />
<uses-permission android:name=”android.permission.CAMERA” />
Our task here is to tell the operating system that a certain activity of the superduper app will be able to deal with the links that have a URL scheme as, for instance, superduper://my_code_is_here .
In the application tag, we have to add an indication to the activity and to the associated URL type.
The activity name goes in the android:name attribute of the application tag. The URL scheme name goes in the android:scheme attribute of the data tag inside the intent-filter, inside the activity, inside the application… like so:
<activity android:icon=”@drawable/Icon” android:label=”superduperapp” android:name=”superduperapp.urlentryclass”>
<action android:name=”android.intent.action.VIEW” />
<category android:name=”android.intent.category.DEFAULT” />
<category android:name=”android.intent.category.BROWSABLE” />
<data android:scheme=”superduperapp” />
We install the app on the device (it works also on the emulator).
As we did with iOS, we open our emulator and navigate to the address that contains the link
When we click, our app opens on the Activity we indicated on the AndroidManifest.xml file (superduperapp.urlentryclass).
The class reads the code that is after the superduperapp:// “protocol” string in the Intent object, with this code:
[Activity (Label = “urlentryclass”)]
public class urlentryclass : Activity
protected override void OnCreate (Bundle bundle)
Intent outsideIntent = Intent;
AlertDialog.Builder CodeAD = new AlertDialog.Builder (this);
CodeAD.SetMessage (“Code: ” + Intent.Data.EncodedAuthority);
This is the result:
Please note four things:
1 – in Xamarin Android, it is better to keep solution, project and class name in lowercase. I have had lots of issues when this wasn’t the case and I’m not entirely sure I was typing the names wrong. I think something may work incorrectly when you use class names LiKe_tHiS.
2 – the application name does NOT have to be the same of the URL scheme. You can register your app “uncommonApp” to deal with any URL: BeautifulThings://, http:// (if you’re making a browser), whatever://
3 – you don’t have to run the app to register the new association. Installation is enough.
4 – the URL association won’t work if you type the URL in a browser. It has to be a link in a web page or in an email.