{"id":3635,"date":"2017-08-25T09:22:47","date_gmt":"2017-08-25T09:22:47","guid":{"rendered":"http:\/\/www.nikola-breznjak.com\/blog\/?p=3635"},"modified":"2017-08-25T09:30:44","modified_gmt":"2017-08-25T09:30:44","slug":"use-deep-linking-ionic-1-apps-ionic-native-deeplinks-plugin","status":"publish","type":"post","link":"https:\/\/nikola-breznjak.com\/blog\/javascript\/ionic\/use-deep-linking-ionic-1-apps-ionic-native-deeplinks-plugin\/","title":{"rendered":"How to use deep linking in Ionic 1 apps with Ionic Native Deeplinks plugin"},"content":{"rendered":"<p>In this tutorial, I&#8217;m going to show you how to use deep linking in <strong>Ionic 1<\/strong> apps with <a href=\"http:\/\/ionicframework.com\/docs\/native\/deeplinks\/\">Ionic Native Deeplinks plugin<\/a> that&#8217;s originally made for Ionic 2 and Ionic 3. Hopefully, I&#8217;ll save you some time so that you won&#8217;t have to figure this out on your own. I&#8217;ll note where the official documentation is lacking in terms of setting the correct link when passing additional parameters.<\/p>\n<p>So, let&#8217;s get started!<\/p>\n<h2>Demo project<\/h2>\n<p>You can check out the code for this project on <a href=\"https:\/\/github.com\/Hitman666\/IonicDeeplinkTest\">Github<\/a>.<\/p>\n<p>Here&#8217;s the app in action, where you&#8217;ll notice how by clicking the link you are taken to the app to a specific screen. Also, additional nesting (opening up the detail screen of one &#8216;chat&#8217;) also works:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/i.imgur.com\/VeDiqnF.gif\" alt=\"\" \/><\/p>\n<h2>Step by step<\/h2>\n<p>Here are the steps you can take to get to the same final working project like the one I&#8217;ve posted on <a href=\"https:\/\/github.com\/Hitman666\/IonicDeeplinkTest\">Github<\/a>.<\/p>\n<p>Start a new Ionic 1 project based on tabs template:<\/p>\n<p><code>ionic start IonicDeeplinkTest tabs<\/code><\/p>\n<p>Add the deeplinks plugin:<\/p>\n<pre><code>ionic plugin add ionic-plugin-deeplinks --variable URL_SCHEME=nikola --variable DEEPLINK_SCHEME=http --variable DEEPLINK_HOST=nikola-breznjak.com --save\n<\/code><\/pre>\n<p>Few things to note here are:<\/p>\n<ul>\n<li><strong>URL_SCHEME<\/strong> &#8211;  a string which you&#8217;ll put in your links so that once clicked your phone&#8217;s operating system will know to open your app. In my case, the links will look like <code>nikola:\/\/something<\/code><\/li>\n<li><strong>DEEPLINK_SCHEME<\/strong> &#8211; most probably you&#8217;ll want to put <strong>https<\/strong> here, but I&#8217;ve put <strong>http<\/strong> because my website doesn&#8217;t (yet) have SSL support ?<\/li>\n<li><strong>DEEPLINK_HOST<\/strong> &#8211;  you should put your domain here on which you&#8217;ll put the link<\/li>\n<\/ul>\n<p>The output of the command above should be something like this:<\/p>\n<pre><code>Fetching plugin \"ionic-plugin-deeplinks\" via npm\n\nInstalling \"ionic-plugin-deeplinks\" for ios\n\nInstalling dependency packages: \n\n{\n  \"mkpath\": \"&gt;=1.0.0\",\n  \"xml2js\": \"&gt;=0.4\",\n  \"node-version-compare\": \"&gt;=1.0.1\",\n  \"plist\": \"&gt;=1.2.0\"\n}\n<\/code><\/pre>\n<p>Now, as mentioned in the <a href=\"http:\/\/ionicframework.com\/docs\/native\/deeplinks\/\">official plugin docs<\/a>, this plugin is originally provided through Ionic Native for Ionic 2+ apps. But, we can use Ionic Native with Ionic 1 if we install it like this (<a href=\"https:\/\/github.com\/ionic-team\/ionic-native\/blob\/v2.x\/README.md\">official docs on this subject<\/a>):<\/p>\n<p><code>npm install ionic-native --save<\/code><\/p>\n<p>Now, copy <code>ionic.native.min.js<\/code> from <code>node_modules\/ionic-native\/dist<\/code> folder into a new <code>lib\/ionic-native<\/code> folder.<\/p>\n<p>Then, in <code>index.html<\/code> add:<\/p>\n<p><code>&lt;script src=\"lib\/ionic-native\/ionic.native.min.js\"&gt;&lt;\/script&gt;<\/code><\/p>\n<p>just before the<\/p>\n<p><code>&lt;script src=\"cordova.js\"&gt;&lt;\/script&gt;<\/code><\/p>\n<p>line.<\/p>\n<p>Next, run the following command:<\/p>\n<p><code>npm install --save @ionic-native\/deeplinks<\/code><\/p>\n<p>Finally, open up the <code>app.js<\/code> file and add the following code inside the <code>platform.ready<\/code> callback:<\/p>\n<pre><code>$cordovaDeeplinks.route({\n    '\/chats\/:chatId': {\n        target: 'tab.chat-detail',\n        parent: 'tab.chats'\n    },\n    '\/account': {\n        target: 'tab.account',\n        parent: 'tab.account'\n    },\n    '\/chats': {\n        target: 'tab.chats',\n        parent: 'tab.chats'\n    }\n}).subscribe(function(match) {\n    $timeout(function() {\n        $state.go(match.$route.parent, match.$args);\n\n        if (match.$route.target != match.$route.parent) {\n            $timeout(function() {\n                $state.go(match.$route.target, {chatId: match.$args.chatId});\n            }, 800);\n        }\n    }, 100); \/\/ Timeouts can be tweaked to customize the feel of the deeplink\n}, function(nomatch) {\n    console.warn('No match', nomatch);\n});\n<\/code><\/pre>\n<p>Also, don&#8217;t forget to add <code>ionic.native<\/code> to the <code>angular.module<\/code> function in the <code>app.js<\/code> file:<\/p>\n<p><code>angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'ionic.native'])<\/code><\/p>\n<p>and inject <code>$cordovaDeeplinks<\/code> in the <code>.run<\/code> function.<\/p>\n<p>Just for reference, the full contents of the app.js file should now look like this:<\/p>\n<pre><code>\/\/ Ionic Starter App\n\n\/\/ angular.module is a global place for creating, registering and retrieving Angular modules\n\/\/ 'starter' is the name of this angular module example (also set in a &lt;body&gt; attribute in index.html)\n\/\/ the 2nd parameter is an array of 'requires'\n\/\/ 'starter.services' is found in services.js\n\/\/ 'starter.controllers' is found in controllers.js\nangular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'ionic.native'])\n\n.run(function($ionicPlatform, $cordovaDeeplinks, $timeout, $state) {\n    $ionicPlatform.ready(function() {\n        \/\/ Hide the accessory bar by default (remove this to show the accessory bar above the keyboard\n        \/\/ for form inputs)\n        if (window.cordova &amp;&amp; window.cordova.plugins &amp;&amp; window.cordova.plugins.Keyboard) {\n            cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);\n            cordova.plugins.Keyboard.disableScroll(true);\n\n        }\n        if (window.StatusBar) {\n            \/\/ org.apache.cordova.statusbar required\n            StatusBar.styleDefault();\n        }\n\n        $cordovaDeeplinks.route({\n            '\/chats\/:chatId': {\n                target: 'tab.chat-detail',\n                parent: 'tab.chats'\n            },\n            '\/account': {\n                target: 'tab.account',\n                parent: 'tab.account'\n            },\n            '\/chats': {\n                target: 'tab.chats',\n                parent: 'tab.chats'\n            }\n        }).subscribe(function(match) {\n            console.log('matching');\n            console.dir(match);\n            $timeout(function() {\n                $state.go(match.$route.parent, match.$args);\n\n                if (match.$route.target != match.$route.parent) {\n                    $timeout(function() {\n                        $state.go(match.$route.target, {chatId: match.$args.chatId});\n                    }, 800);\n                }\n            }, 100); \/\/ Timeouts can be tweaked to customize the feel of the deeplink\n        }, function(nomatch) {\n            console.warn('No match', nomatch);\n            console.dir(nomatch);\n        });\n    });\n})\n\n.config(function($stateProvider, $urlRouterProvider) {\n\n    \/\/ Ionic uses AngularUI Router which uses the concept of states\n    \/\/ Learn more here: https:\/\/github.com\/angular-ui\/ui-router\n    \/\/ Set up the various states which the app can be in.\n    \/\/ Each state's controller can be found in controllers.js\n    $stateProvider\n\n    \/\/ setup an abstract state for the tabs directive\n        .state('tab', {\n        url: '\/tab',\n        abstract: true,\n        templateUrl: 'templates\/tabs.html'\n    })\n\n    \/\/ Each tab has its own nav history stack:\n\n    .state('tab.dash', {\n        url: '\/dash',\n        views: {\n            'tab-dash': {\n                templateUrl: 'templates\/tab-dash.html',\n                controller: 'DashCtrl'\n            }\n        }\n    })\n\n    .state('tab.chats', {\n            url: '\/chats',\n            views: {\n                'tab-chats': {\n                    templateUrl: 'templates\/tab-chats.html',\n                    controller: 'ChatsCtrl'\n                }\n            }\n        })\n        .state('tab.chat-detail', {\n            params: {chatId: 0},\n            url: '\/chats\/:chatId',\n            views: {\n                'tab-chats': {\n                    templateUrl: 'templates\/chat-detail.html',\n                    controller: 'ChatDetailCtrl'\n                }\n            }\n        })\n\n    .state('tab.account', {\n        url: '\/account',\n        views: {\n            'tab-account': {\n                templateUrl: 'templates\/tab-account.html',\n                controller: 'AccountCtrl'\n            }\n        }\n    });\n\n    \/\/ if none of the above states are matched, use this as the fallback\n    $urlRouterProvider.otherwise('\/tab\/dash');\n});\n<\/code><\/pre>\n<p>A few example links that you should put on your website look like this:<\/p>\n<pre><code>&lt;a href=\"nikola:\/\/account\"&gt;Open Account&lt;\/a&gt;\n&lt;a href=\"nikola:\/\/chats\"&gt;Open Chats&lt;\/a&gt;\n&lt;a href=\"nikola:\/\/app\/chats\/4\"&gt;Open chat detail 4&lt;\/a&gt;\n<\/code><\/pre>\n<p>I created a simple demo page so you can test this if you&#8217;d like and it&#8217;s <a href=\"http:\/\/nikola-breznjak.com\/apps\/IonicDeeplinkTesting\/\">here<\/a>. Just open this link on your phone, after you&#8217;ve run the demo app on your phone and you should see the links working &#8211; meaning; taking you to proper sections in the app.<\/p>\n<p>Just for reference, the contents of that file is this:<\/p>\n<pre><code>&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n&lt;head&gt;\n    &lt;title&gt;Deeplinking test&lt;\/title&gt;\n\n    &lt;style type=\"text\/css\"&gt;\n        a {\n            font-size: 80px;\n            margin: 40px;\n            display: block;\n        }\n\n        body {\n            text-align: center;\n        }\n    &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;a href=\"nikola:\/\/account\"&gt;Open Account&lt;\/a&gt;\n\n    &lt;a href=\"nikola:\/\/chats\"&gt;Open Chats&lt;\/a&gt;\n\n    &lt;a href=\"nikola:\/\/app\/chats\/4\"&gt;Open chat detail 4&lt;\/a&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n<p><strong>The most important part<\/strong> here, on which I&#8217;ve wasted most of the time is the <code>nikola:\/\/app\/chats\/4<\/code> part. Namely, at first I expected that you only should write it as <code>nikola:\/\/chats\/4<\/code>, but by finding the <a href=\"https:\/\/github.com\/ionic-team\/ionic-plugin-deeplinks\/issues\/63\">bug report<\/a> about this in the official repo I realized that you have to put something as a suffix (I&#8217;ve put <code>app<\/code> here).<\/p>\n<p>Now, to run the app on your device, first prepare it:<\/p>\n<p><code>ionic prepare ios<\/code><\/p>\n<p>Then, open the <code>platforms\/ios\/IonicDeeplinkTest.xcodeproj<\/code> file:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/i.imgur.com\/4SFXq7N.png\" alt=\"\" \/><\/p>\n<p>And, make sure the string <code>nikola<\/code> (of course, change this string to your use case &#8211; usually the name of the app) is set as shown on the image:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/i.imgur.com\/ZmYJBIG.png\" alt=\"\" \/><\/p>\n<p>For any potential additional info about setting up Xcode, check the <a href=\"http:\/\/blog.ionic.io\/deeplinking-in-ionic-apps\/\">official blog post<\/a>.<\/p>\n<p>Here&#8217;s the app in action, where you&#8217;ll notice how by clicking the link you are taken to the app to a specific screen. Also, additional nesting (opening up the detail screen of one &#8216;chat&#8217;) also works by passing in the argument.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/i.imgur.com\/VeDiqnF.gif\" alt=\"\" \/><\/p>\n<h2>Conclusion<\/h2>\n<p>I hope this was helpful and that it saved you some time in trying to figure this out.<\/p>\n<p>In case you&#8217;re wondering how to do this for Ionic 2, 3+ apps, then it&#8217;s even easier as shown in the <a href=\"http:\/\/ionicframework.com\/docs\/native\/deeplinks\/\">official docs<\/a>.<\/p>\n<blockquote class=\"twitter-tweet\" data-width=\"550\">\n<p lang=\"en\" dir=\"ltr\">How to use deep linking in Ionic 1 apps with Ionic Native Deeplinks plugin <a href=\"https:\/\/t.co\/dAtt4Fwv3o\">https:\/\/t.co\/dAtt4Fwv3o<\/a><\/p>\n<p>&mdash; Nikola Bre\u017enjak (@HitmanHR) <a href=\"https:\/\/twitter.com\/HitmanHR\/status\/901013716958924800\">August 25, 2017<\/a><\/p><\/blockquote>\n<p><script async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, I&#8217;m going to show you how to use deep linking in Ionic 1 apps with Ionic Native Deeplinks plugin that&#8217;s originally made for Ionic 2&hellip;<\/p>\n","protected":false},"author":1,"featured_media":3636,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[43],"tags":[],"class_list":["post-3635","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ionic"],"_links":{"self":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3635","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/comments?post=3635"}],"version-history":[{"count":2,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3635\/revisions"}],"predecessor-version":[{"id":3638,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3635\/revisions\/3638"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media\/3636"}],"wp:attachment":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media?parent=3635"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/categories?post=3635"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/tags?post=3635"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}