Using Custom URL Schemes In Your Ionic Framework App

Using Custom URL Schemes In Your Ionic Framework App

posted in: Uncategorized | 35

There is a growing transparency between the web and applications.  Users want a seamless experience when finding and using information on the internet.

Companies such as Google, Yelp and Twitter already offer this deep linking experience in their search results and mobile applications.  Take the following for example:

market://details?id=com.nraboy.otpsafe

If you were to open the above from an Android web browser, it would open using the Google Play application instead.

Mobile applications made with Ionic Framework can leverage custom URL schemes without issue thanks to a great Apache Cordova plugin called LaunchMyApp by Eddy Verbruggen.

To get us started, lets create a fresh Ionic Framework Android and iOS project:

ionic start IonicProject blank
cd IonicProject
ionic platform add android
ionic platform add ios

Note that if you’re not using a Mac, you cannot add and build for the iOS platform.

The next thing we want to do is add the plugin into our project.  If you’re familiar with adding plugins to Apache Cordova or Ionic Framework projects, please pay attention because what we’re going to do is slightly different:

cordova plugin add https://github.com/EddyVerbruggen/LaunchMyApp-PhoneGap-Plugin.git --variable URL_SCHEME=ionicapp

Notice the --variable URL_SCHEME=ionicapp we included at the end of the command.  It is essential otherwise the plugin will fail to add.  However, you can replace ionicapp with whatever you’d like representing your application.  If you choose to keep the URL scheme as ionicapp then you will be able to launch your application from any URL that starts like this:

ionicapp://

It doesn’t need to end there.  You could listen in your application for various URL paths and parameters and have your application do various things depending.  Add the following code globally:

var handleOpenURL = function(url) {
    alert("RECEIVED URL: " + url);
};

When I say globally, I mean outside any AngularJS method or controller.  This is because the URL scheme will probably load and launch before the
$ionicPlatform.ready() or onDeviceReady() methods fire.  The LaunchMyApp plugin is going to look for the handleOpenURL(url) method.

Because the function is global it won’t be tied to any AngularJS.  With that said, you wont be able to change states or do any fancy AngularJS stuff.  To get around this you should set a local storage indicator.  If you’re unfamiliar with local storage, you can check out a previous article I made on the topic.  You might do something like this:

var handleOpenURL = function(url) {
    window.localStorage.setItem("external_load", url);
};

Then in your $ionicPlatform.ready() or onDeviceReady() methods you can see if external_load has been set.  If it has, then do something with AngularJS and clear the item from local storage.

A video version of this article can be seen below.

Application Developer | Android, Java, Ionic Framework, SQL, Unity3D, and AngularJS

35 Responses

  1. Great article, thanks for sharing. Quick question: If your app isn’t installed on the device, does nothing happen when you click/open a link with a custom url scheme?

  2. It will just try to open in your web browser.

  3. Great article, any suggestions on how to do this in Phonegap build?

  4. waqas khan

    Hi Nic Raboy
    Nice article , is it possible how can i redirect to app store if app is not store in device? its working for me if app is install in device so how could possible if app is not install it would redirect to play store for download.

    thank you

    • I can’t imagine this being possible. Android and iOS don’t make relationships or their own custom schemes to apps in their marketplaces.

      If you can show me an example of this happening, I’d love to see it.

      Regards,

      • sorry i mean to say how can i redirect to android playstore.

        • Hey Waqas,

          As Nic was saying, I don’t believe this is possible. When you installed the app on the phone, that is when your scheme is registered with the device.

          If the app is not installed, your device will have no idea what that scheme is and will simply give the user a message telling them so.

        • The Play Store scheme is market://. You’ll still need to know the the app package name ex: com.your.app

  5. Hi guys,

    what about this solution?

    http://www.appsflyer.com/create-one-smart-link-any-use-case-appsflyer-releases-onelink/

    do you think it could work?

    • It seems like it could work as an alternate solution, but that is if you don’t mind using a hosted service to accomplish the job. By making use of a custom URL scheme directly in your app, you get a more integrated experience.

  6. BulletPoint

    Will LaunchMyApp also act as an WebIntent? I’m trying to get my app to appear in the list of available apps to share data from other apps with. So for example, Could the path to an image from the photo album be passed via this custom URL scheme as a parameter? Or how might that be done in iOS/android?

  7. On iOS it doesn’t work first time you lunch the app. If you go back to the browser it will work.

  8. Before you choose your URL scheme, you might want to first check that it does not clash with schemes of existing apps.

    http://handleopenurl.com/ has a list ones registered for iOS (sorry not Android).
    http://wiki.akosma.com/IPhone_URL_Schemes

  9. Hi @nic,

    Thanks for the article, by following the article, I was able to get my app working. But I have an issue,

    What I’m trying to do is, open up a specific page depending on the params I pass. But the problem is

    When the app is close

    ** It open ups the app, but doesn’t open up the specific page

    When the app is open

    ** it navigate to the correct page

    Following is a public gist, which has the code I tried

    https://gist.github.com/sameera207/4cf93cb65970eac6f92c

    any help would be much appreciated,

    cheers

    Sam

    • Hi Sam,

      You should not try to navigate inside your handleOpenUrl() method. You should store everything passed into local storage and then process a redirect inside your AngularJS run() method based on logic that you’ve put into place and the data that you just stored. Just like I mentioned at the bottom of the article.

      Does that make sense?

      Regards,

  10. @waqas
    The way you solve an issue with not installed app is that you have an http link rather than reviyou:// link. First of of it’ll show links properly. Second – you’ll redirect to your website(if you have one). On the website your javascript will run reviyou:// link or redirect to the download page after 3000 timeout. This way if you have no app installed you’ll install it, and if you already have an app installed – it’ll be just a redirect.

    That said – it’s also better for the long term to have a valid http links if you are using “share” functionality bw different users.

    Alex

    Also Nic is not 100% correct with his idea of using local storage i believe. Problem with that is that application could be opened already so ondeviceready would not run at all. That’s why inside of your handleOpenUrl you still want to do window.location as well and handle both cases, not just one or another.

    • Good answer Alex! I didn’t think of that other scenario.

      • I think the better solution instead of doing window.location is to register listeners in your app module / controller.

        document.addEventListener(“resume”, processLocalStorage);

        The issue with calling window.location from handleOpenURL, is if the app is already running and the window.location works, you’re left with a url still in your local storage. The next time the app closes and opens again it’s going to find it and redirect immediately.

        This still doesn’t solve the issue of when handleOpenURL is called *after* device is ready, which is apparently happening in some cases.

  11. Yakob Ubaidi

    thank you sir. You help me alot.

  12. Dear Nic,

    Thanks for your articles and videos.

    I am trying to use social media share and Custom URL Schemes in a single app.

    When i use the custom URL scheme as a link in social media share function, the link is coming as a plain text in the social media. Can you suggest a solution to fix this.

    • It is up to the social networking site to determine how to parse and display URL links. Chances are they will never recognize your custom scheme link unless you make it big and they plan to add you to their list.

  13. Rahul Yadav

    after add this function

    var handleOpenURL = function(url) {
    alert(“RECEIVED URL: ” + url);
    };

    alert not show

    but after remove url alert show

    var handleOpenURL = function() {
    alert(“RECEIVED URL: ” + url);
    };

    alert(RECEIVED URL: undefined);

  14. As mentioned by @waqas above, this solution isn’t 100% foolproof. You need to handle three cases: when an app is starting cold and handleOpenURL runs before your code, a cold open when it runs after your code, or when the app is already running in the background. One way to solve this is to dispatch an event after you set the local storage:

    “`
    var handleOpenURL = function(url) {
    window.localStorage.setItem(“external_load”, url);
    var evt = new Event(‘myapp-deeplink’);
    document.dispatchEvent(evt);
    };
    “`

    and then in your angular app controller:
    “`

    document.addEventListener(‘myapp-deeplink’, processExternalLoad);
    “`

    Local storage will solve the cold start before your app is initialized, and once your app is running it should be listening to the event.

  15. The problem:

    Iam trying to make the url scheme to work on ionic / ios.

    I am using the :
    cordova plugin add https://github.com/EddyVerbruggen/LaunchMyApp-PhoneGap-Plugin.git –variable URL_SCHEME=ionicapp

    If i start a new project and put this code on the beginning of app.js, it works when i call ionicapp:// on browser:

    var handleOpenURL = function(url) {
    setTimeout(function() {
    alert(“RECEIVED URL: ” + url);
    }, 3000);
    };

    But the problem is… when I put this on my “big” project, my app is called when the url scheme is used on browser, but there´s no alert message! And I cannot debug, because nothing appear on Xcode console log…

    So, what I want is a way to discover WHY this is not working… did you suggest a way to debug/log/test?

    • Try to debug it like this for iOS:

      https://blog.nraboy.com/2015/10/debugging-your-apache-cordova-ios-app-with-safari/

      Also, does it work for Android?:

      https://blog.nraboy.com/2014/12/debugging-android-source-code-adb/

      Regards,

      • Yes, already used the safari debug, no errors on console.

        Is, it´s working on android!!

        I´ve tried to put in the END of app.js this code:

        function handleOpenURL(url) {
        console.log(‘received url = ‘+url);
        alert(‘received url = ‘+url);
        };

        and when i call myapp:// on an android browser, my app opens and the alert message shows with URL.

        on iOS, app opens, and nothing happens =(

        • If it works in your new project, your problem must exist in your existing project. Maybe you have some typos within your application. The only thing I can suggest is running your code through a linter and searching very carefully for the problem.

          You can also open an issue ticket with the developer if you think it is a bug without errors:

          https://github.com/EddyVerbruggen/Custom-URL-scheme/issues

          Knowing that it works in a new project and you don’t have errors I cannot help you.

          Sorry,

          • Getulio JR

            nraboy, do you read about “it´s working on android”?

            I´am telling you that in MY BIG PROJECT it´s working on android, not in a brand new project. This is not working on iOS, but works on android.

            So, it´s a problem on iOS deploy only… and that´s where I want some help.

            If you dont understand, ok. Thanks anyway.

  16. Can I add the one that will take me to Google playstore straight instead of web browser?

    • The Google Play app already has a custom scheme registered, like I mentioned at the beginning of the post. If you use the package and the market:// url, it will take you to the app in the store.

Leave a Reply