Opening a mobile app from a link: the Xamarin way (URL-Schemes)

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”.

Xamarin Studio for iOS screenshot

How to edit Info.plist in Xamarin Studio

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)
{
Console.WriteLine (url);
/* 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 */
return true;
}

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:

<a href=”superduperapp://my_code_is_here”>superduperapp_link</a>

which visually translates into this:

Link with custom URL schema to open our app

A link with a custom URL looks exactly as any link. In it, we might have a personal URL scheme, as superduperapp in our case

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:

this is how the code shows once we open the app via the custom URL

iPhone or iPad app done in Xamarin, opened by custom URL

Please note:

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&#8221; android:versionCode=”1″ android:versionName=”1.0″ package=”superduperapp.superduperapp”>
<uses-sdk android:minSdkVersion=”19″ android:targetSdkVersion=”19″ />
<application android:label=”superduperapp”></application>
<uses-permission android:name=”android.permission.CAMERA” />
</manifest>

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:

<application android:label=”superduperapp”>
<activity android:icon=”@drawable/Icon” android:label=”superduperapp” android:name=”superduperapp.urlentryclass”>
<intent-filter>
<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” />
</intent-filter>
</activity>
</application>

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

<a href=”superduperapp://my_code_is_here”>superduperapp_link</a>

Link in android device

Link to open android app from custom 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)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);

Intent outsideIntent = Intent;
AlertDialog.Builder CodeAD = new AlertDialog.Builder (this);

CodeAD.SetTitle (“Superduperapp”);
CodeAD.SetMessage (“Code: ” + Intent.Data.EncodedAuthority);
CodeAD.Show ();
}
}

This is the result:

this is the screenshot of the Android app opened by the custom URL scheme

the Android app opened by our custom URL

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.

3 thoughts on “Opening a mobile app from a link: the Xamarin way (URL-Schemes)

  1. Thanks for the writeup! Wish there was a download project so I can cross reference.

    Either way this is a great help. Would be nice to annotate this blog with the validated deep linking apple does to prevent other apps from hijacking your namespace.

    Like

  2. Thanks much for writing this, it was a huge help!

    For me to get android to find the class correctly though I had to replace this:
    [Activity (Label = “urlentryclass”)]

    With this:
    [Activity (Name = “com.mycompany.urlentryclass”)]

    And then within the android manifest I had to use that fully qualified name.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s