{"id":3845,"date":"2017-12-15T17:54:29","date_gmt":"2017-12-15T17:54:29","guid":{"rendered":"http:\/\/www.nikola-breznjak.com\/blog\/?p=3845"},"modified":"2017-12-15T18:08:54","modified_gmt":"2017-12-15T18:08:54","slug":"polish-existing-ionic3-calculator-application","status":"publish","type":"post","link":"https:\/\/nikola-breznjak.com\/blog\/javascript\/ionic3\/polish-existing-ionic3-calculator-application\/","title":{"rendered":"How to polish our existing Ionic3 calculator application"},"content":{"rendered":"<p>This is the third post in a series of posts which will teach you how to take advantage of your web development knowledge in building hybrid applications for iOS and Android. The first post in this series was all about <a href=\"http:\/\/www.nikola-breznjak.com\/blog\/javascript\/ionic3\/get-started-ionic-framework-3-mac-windows\/\">How to get started with Ionic framework 3 on Windows and Mac<\/a>, the second one was about <a href=\"http:\/\/www.nikola-breznjak.com\/blog\/javascript\/ionic3\/create-calculator-application-ionic-framework-3-using-ionic-creator-ui\/\">How to create a calculator application with Ionic framework 3 by using Ionic Creator for UI<\/a>.<\/p>\n<p>In this post you&#8217;ll learn:<\/p>\n<ul>\n<li>How to polish your existing calculator application<\/li>\n<li>How to create icons and splash screen images automatically<\/li>\n<li>How to implement Google AdMob ads<\/li>\n<li>How to share your application with other users without going through the app stores<\/li>\n<li>How to test your application on the real physical devices and emulators<\/li>\n<\/ul>\n<p>So, if you&#8217;ve been following these series of posts then you probably already have the Calculator application ready and running on your machine in the web browser by using the <code>ionic lab<\/code> command.<\/p>\n<p>If you just dropped by, or you would like to start from scratch, then you can clone the finished version of the 2nd tutorial from <a href=\"https:\/\/github.com\/Hitman666\/Ionic3_2ndTutorial\">Github<\/a>. After cloning, you have to run <code>npm install<\/code> to install all the dependencies. After this, the command <code>ionic lab<\/code> should run the application locally on your computer, and you should see it open up in your default browser. <em>Of course, all this should work if you have Ionic properly installed. If not, please check out the instructions in the <a href=\"http:\/\/www.nikola-breznjak.com\/blog\/javascript\/ionic3\/get-started-ionic-framework-3-mac-windows\/\">first tutorial<\/a>.<\/em><\/p>\n<p>At this point, we have a working simple calculator application that lacks some sanitization checks and design improvements. We&#8217;ll fix that in this section.<\/p>\n<h2>Sanitization check<\/h2>\n<p>In our current application, we don&#8217;t have a security measure against the possible malformed input. For example, one could enter two plus (<code>+<\/code>) signs one after another, which would consequently produce an error.<\/p>\n<p>So, to handle this, we&#8217;re going to wrap our evaluation line of code in the <code>try\/catch<\/code> block, and we&#8217;re going to show an alert to the user using the <a href=\"https:\/\/ionicframework.com\/docs\/api\/components\/alert\/AlertController\/\">AlertController<\/a> dialog (injected as a dependency in the <code>CalculatorPage<\/code> class constructor). The whole contents of the <code>calculator.ts<\/code> file should look like this now:<\/p>\n<pre><code>import { Component } from '@angular\/core';\nimport { NavController } from 'ionic-angular';\nimport { AlertController } from 'ionic-angular';\n\n@Component({\n    selector: 'page-calculator',\n    templateUrl: 'calculator.html'\n})\nexport class CalculatorPage {\n    constructor(public navCtrl: NavController, private alertCtrl: AlertController) { }\n\n    result = '';\n\n    btnClicked(btn) {\n        if (btn == 'C') {\n            this.result = '';\n        }\n        else if (btn == '=') {\n            if (this.result == '') {\n                return;\n            }\n\n            try {\n                this.result = eval(this.result).toFixed(2);\n            } catch (error) {\n                this.showAlert();\n                this.result = '';\n            }\n        }\n        else {\n            this.result += btn;\n        }\n    }\n\n    showAlert() {\n        this.alertCtrl.create({\n            title: 'Malformed input',\n            subTitle: 'Ooops, please try again...',\n            buttons: ['Dismiss']\n        }).present();\n    }\n}\n<\/code><\/pre>\n<p>Additionally, we&#8217;re checking to see if the <code>result<\/code> variable contains anything at the time the equals button is pressed, to avoid the <code>undefined<\/code> error that would otherwise happen. <em>You can test this yourself by running the application clicking the equals button <code>=<\/code> and then on, for example, button <code>5<\/code>, and you will see the text <code>undefined5<\/code> appear in the Result area.<\/em><\/p>\n<p>Also, you may have noticed that we added the <a href=\"http:\/\/www.w3schools.com\/jsref\/jsref_tofixed.asp\">toFixed(2)<\/a> after our <code>eval<\/code> function call, to show the result formatted to <strong>two decimal places<\/strong>.<\/p>\n<p>If you intentionally make an error while inputting the formula you would get this message:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/VNaGioK.png\" alt=\"\" \/><\/p>\n<blockquote><p>\n  Clearly, there are multiple ways you could approach this problem further to create a better user experience. One idea is to check on every button click if the current formula would execute correctly with <code>eval<\/code> and if not then immediately inform the user, or completely ignore the last clicked button. I encourage you to create your own way of the &#8220;improved <a href=\"https:\/\/en.wikipedia.org\/wiki\/User_experience\">UX<\/a>&#8221; and share it in the comments.\n<\/p><\/blockquote>\n<h2>Design changes<\/h2>\n<p>To be honest, our app currently doesn&#8217;t look quite <em>representative<\/em>. We&#8217;re going to change that to make it a bit nicer. If you ask any web designer these days, they will tell you that using pure CSS is, well, outdated. Ionic, as awesome as it is, has support for <a href=\"http:\/\/sass-lang.com\/\">SASS<\/a> out of the box so you can take advantage of the variables, nesting, mixins and all other great stuff that SASS provides.<\/p>\n<p>For example, if you want to change the color you only need to change one variable, without having to trace it through all the files and change the particular color in all the places that it is used.<\/p>\n<p>In the <a href=\"www.nikola-breznjak.com\/blog\/javascript\/ionic3\/create-calculator-application-ionic-framework-3-using-ionic-creator-ui\/\">previous tutorial<\/a> we added the &#8216;energized&#8217; color to the colors array in the <code>src\/theme\/variables.scss<\/code> file. Now we&#8217;re going to do all of our changes in the <code>pages\/calculator\/calculator.scss<\/code> file, which, for now, looks like this:<\/p>\n<pre><code>page-calculator {\n\n}\n<\/code><\/pre>\n<p>These changes will only apply to this page. If we&#8217;d like to add some styles that would apply to our whole app, we can do so in the <code>src\/app\/app.scss<\/code> file.<\/p>\n<p>On the image below you can see what I came up with after changing few of the CSS rules, (and a slight addition to our HTML template that I&#8217;ll address additionally):<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/Av1obHq.png\" alt=\"\" \/><\/p>\n<p>I&#8217;m sure that more design-inclined readers will come up with way more slick design than this and I encourage you to share your images\/scss changes with the rest of us.<\/p>\n<p>Now we&#8217;re going to go through the parts that were changed so that you can follow along in your example and see for yourself.<\/p>\n<p>As for the changes, here is the final content of the <code>src\/pages\/calculator\/calculator.html<\/code> file:<\/p>\n<pre><code>&lt;ion-header&gt;\n    &lt;ion-navbar&gt;\n        &lt;ion-title&gt;\n            SuperSimple Calculator\n        &lt;\/ion-title&gt;\n    &lt;\/ion-navbar&gt;\n&lt;\/ion-header&gt;\n\n&lt;ion-content&gt;\n    &lt;div class=\"container\"&gt;\n        &lt;form class=\"myInputRow\"&gt;\n            &lt;ion-item&gt;\n                &lt;ion-input type=\"text\" placeholder=\"0\" name=\"display\" [(ngModel)]=\"result\"&gt;&lt;\/ion-input&gt;\n            &lt;\/ion-item&gt;\n        &lt;\/form&gt;\n\n        &lt;div class=\"row\"&gt;\n            &lt;button class=\"col2\" ion-button color=\"danger\" (click)=\"btnClicked('C')\"&gt; C &lt;\/button&gt;\n            &lt;button class=\"col\" ion-button color=\"energized\" (click)=\"btnClicked('%')\"&gt; % &lt;\/button&gt;\n            &lt;button class=\"col\" ion-button color=\"energized\" (click)=\"btnClicked('\/')\"&gt; \/ &lt;\/button&gt;\n        &lt;\/div&gt;\n\n        &lt;div class=\"row\"&gt;\n            &lt;button class=\"col\" ion-button (click)=\"btnClicked('7')\"&gt; 7 &lt;\/button&gt;\n            &lt;button class=\"col\" ion-button (click)=\"btnClicked('8')\"&gt; 8 &lt;\/button&gt;\n            &lt;button class=\"col\" ion-button (click)=\"btnClicked('9')\"&gt; 9 &lt;\/button&gt;\n            &lt;button class=\"col\" ion-button color=\"energized\" (click)=\"btnClicked('*')\"&gt; * &lt;\/button&gt;\n        &lt;\/div&gt;\n\n        &lt;div class=\"row\"&gt;\n            &lt;button class=\"col\" ion-button (click)=\"btnClicked('4')\"&gt; 4 &lt;\/button&gt;\n            &lt;button class=\"col\" ion-button (click)=\"btnClicked('5')\"&gt; 5 &lt;\/button&gt;\n            &lt;button class=\"col\" ion-button (click)=\"btnClicked('6')\"&gt; 6 &lt;\/button&gt;\n            &lt;button class=\"col\" ion-button color=\"energized\" (click)=\"btnClicked('-')\"&gt; - &lt;\/button&gt;\n        &lt;\/div&gt;\n\n        &lt;div class=\"row\"&gt;\n            &lt;button class=\"col\" ion-button (click)=\"btnClicked('1')\"&gt; 1 &lt;\/button&gt;\n            &lt;button class=\"col\" ion-button (click)=\"btnClicked('2')\"&gt; 2 &lt;\/button&gt;\n            &lt;button class=\"col\" ion-button (click)=\"btnClicked('3')\"&gt; 3 &lt;\/button&gt;\n            &lt;button class=\"col\" ion-button color=\"energized\" (click)=\"btnClicked('+')\"&gt; + &lt;\/button&gt;\n        &lt;\/div&gt;\n\n        &lt;div class=\"row\"&gt;\n            &lt;button class=\"col\" ion-button (click)=\"btnClicked('0')\"&gt; 0 &lt;\/button&gt;\n            &lt;button class=\"col\" ion-button (click)=\"btnClicked('.')\"&gt; . &lt;\/button&gt;\n            &lt;button class=\"col2\" ion-button color=\"danger\" (click)=\"btnClicked('=')\"&gt; = &lt;\/button&gt;\n        &lt;\/div&gt;\n    &lt;\/div&gt;\n&lt;\/ion-content&gt;\n<\/code><\/pre>\n<p>Here is the breakdown of the changes that I did:<\/p>\n<ul>\n<li>changed the title to <code>SuperSimple Calculator<\/code> from just <code>Calculator<\/code> on the <code>ion-title<\/code> tag<\/li>\n<li>removed all the <code>id<\/code> attributes<\/li>\n<li>removed the <code>ion-label<\/code> in the <code>form<\/code> element<\/li>\n<li>added the <code>myInputRow<\/code> class to the <code>form<\/code> element<\/li>\n<li>added the <code>row<\/code> class to the <code>div<\/code> elements<\/li>\n<li>added the <code>col<\/code> class to the <code>button<\/code> elements, except <code>+<\/code> and <code>=<\/code> buttons to which I&#8217;ve added the <code>col2<\/code> class<\/li>\n<li>wrapped everything in a div with the <code>container<\/code> class<\/li>\n<\/ul>\n<p>In the <code>scss\/ionic.app.scss<\/code> file I added the definitions for these new classes:<\/p>\n<pre><code>page-calculator {\n    .container {\n        display: flex;\n        flex-direction: column;\n        height: 100%;\n\n        .row {\n            flex: 2;\n            flex-direction: row;\n            padding: 0px !important;\n            margin: 0px !important;\n\n            .col {\n                flex: 1;\n                padding: 0px !important;\n                margin: 0px !important;\n            }\n\n            .col2 {\n                flex: 2;\n                padding: 0px !important;\n                margin: 0px !important;\n            }\n        }\n\n        .myInputRow {\n            flex: 1 !important;\n\n            input {\n                font-size: 40px;\n                text-align: right;\n            }\n        }\n\n        button {\n            height: auto !important;\n            border-radius: 0px !important;\n            font-size: 32px;\n            font-weight: bold;\n            border-left: 1px solid #fff;\n            border-bottom: 1px solid #fff;\n        }\n    }\n}\n<\/code><\/pre>\n<p>Flexbox is used here as a basis for making the layout which fills the whole content horizontally. You can learn more about it from <a href=\"http:\/\/www.joshmorony.com\/how-to-create-complex-layouts-in-ionic\/\">this Ionic specific tutorial<\/a>, or you can learn more about Flexbox in general from <a href=\"https:\/\/css-tricks.com\/snippets\/css\/a-guide-to-flexbox\/\">this tutorial<\/a>.<\/p>\n<p>This way we now have an interface which fills the whole available content.<\/p>\n<h2>How to create icons and splash screen images automatically in Ionic framework 3<\/h2>\n<p>The icon is an important part of your application because it represents your application&#8217;s brand, and it helps to identify quickly where the app is on your phone. In case you&#8217;re familiar with creating apps then you will remember that it is a tedious process to create a lot of different size images both for iOS and Android platforms.<\/p>\n<p>Also, the same goes for the so-called splash screen that shows up every time the application starts. Although having a splash screen is not mandatory, it certainly adds up to the feeling of a complete and professional application, which one would certainly want to convey with his application.<\/p>\n<p>Ionic helps tremendously with this by providing a single Ionic CLI command to generate all the needed icon and splash screen sizes for us automatically. Also, Ionic created <a href=\"http:\/\/code.ionicframework.com\/resources\/splash.psd\">Photoshop Splash Screen Template<\/a>, which you can download for free and use as a guideline for creating an icon. However, if you create you project by using <code>ionic start<\/code> command, as we have, then you&#8217;ll already have both the <code>icon.png<\/code> and <code>splash.png<\/code> files in the <code>resources<\/code> folder, and you can just edit them.<\/p>\n<p>For when you&#8217;re creating a branded product having a custom made icon is definitely a must. However, in this case, I&#8217;ll show you how to use one of the free services to search for a free icon which you&#8217;ll then use in your application (even if your application is a commercial application).<\/p>\n<p>I tend to use <a href=\"https:\/\/www.iconfinder.com?ref=Hitman666\">IconFinder<\/a> a lot, and here are the settings which you have to use to filter out the calculator images that are Free (PRICE) and can be used in commercial applications and that don&#8217;t even require a link back (LICENSE TYPE).<\/p>\n<p>Of course, you can also choose to buy an image if you happen to find one that you like. You can additionally search by format, size, and background. The filters should look like this (use this <a href=\"https:\/\/www.iconfinder.com\/search\/?q=calculator&amp;license=2&amp;minimum=512&amp;maximum=512&amp;price=free&amp;ref=Hitman666\">prepared link which sets them automatically<\/a>):<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/IIi4opI.png\" alt=\"\" \/><\/p>\n<p>I&#8217;m going to use the last one in the first row. Simply click on it, and you should get to the download page that looks like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/BtvGIBC.png\" alt=\"\" \/><\/p>\n<p>To download it just click on the green &#8216;Download PNG&#8217; button.<\/p>\n<p>Now, in the <code>resources<\/code> folder find and open the <code>icon.png<\/code> file with an image editor of your choice. I&#8217;m going to use <a href=\"https:\/\/www.gimp.org\/\">Gimp<\/a> in this example as it&#8217;s free cross-platform image editor available for all the major operating systems (Linux, OS X, Windows). You should see something like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/lLbXt9G.png\" alt=\"\" \/><\/p>\n<p>Now you need to do a few steps:<\/p>\n<ul>\n<li>select the whole area (<code>Ctrl + a<\/code> or <code>Command + a<\/code>) and press the <code>DEL<\/code> button on your keyboard. This should leave you with a blank white canvas.<\/li>\n<li>drag the calculator icon on this white canvas and you should see something like this: <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/00hlTzE.png\" alt=\"\" \/><\/li>\n<li>click on the scale tool<\/li>\n<li><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/yFIhdhT.png\" alt=\"\" \/><\/li>\n<li>then click on the calculator image. You should get this popup:<\/li>\n<li><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/O9UnBaW.png\" alt=\"\" \/><\/li>\n<li>change the values in the popup to <code>1024px<\/code> for both Width and Height and click the <code>Scale<\/code> button.<\/li>\n<li>click on the Alignment Tool, then click on the calculator image and then on the circled two buttons on the image below. This will align the calculator image horizontally and vertically<\/li>\n<li><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/3uFV529.png\" alt=\"\" \/><\/li>\n<\/ul>\n<p>Now save the file by going to <code>File-&gt;Overwrite icon.png<\/code>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/4C8mzLi.png\" alt=\"\" \/><\/p>\n<p>Repeat the process to create the splash screen image and name it (overwrite it as) <code>splash.png<\/code>. The image I came up with looks like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/a10DZi5.png\" alt=\"\" \/><\/p>\n<p>Now that you have both <strong>icon.png<\/strong> and <strong>splash.png<\/strong> images ready, navigate with your Terminal\/Command prompt to the root folder of the application and run the following command:<\/p>\n<p><code>ionic cordova resources<\/code><\/p>\n<p>You should get the following output:<\/p>\n<pre><code>\u2714 Collecting resource configuration and source images - done!\n\u2714 Filtering out image resources that do not need regeneration - done!\n\u2714 Uploading source images to prepare for transformations - done!\n\u2714 Generating platform resources: 48 \/ 48 complete - done!\n\u2714 Modifying config.xml to add new image resources - done!\n<\/code><\/pre>\n<p>If, instead, at this point, you get an error like this:<\/p>\n<p><code>[ERROR] No platforms have been added. Please run: ionic cordova platform add<\/code><\/p>\n<p>That means that you haven&#8217;t added any platforms yet to which Ionic should build. Since we&#8217;re going to build the app for both Apple Store and Android Play Store we&#8217;re going to use the following two commands:<\/p>\n<pre><code>ionic cordova platform add android\nionic cordova platform add ios\n<\/code><\/pre>\n<p>You should see an output similar to this:<\/p>\n<pre><code>ionic cordova platform add ios\n&gt; cordova platform add ios --save\n\u2714 Running command - done!\nUsing cordova-fetch for cordova-ios@~4.4.0\nAdding ios project...\nCreating Cordova project for the iOS platform:\n    Path: platforms\/ios\n    Package: io.ionic.starter\n    Name: MyApp\niOS project created with cordova-ios@4.4.0\nDiscovered plugin \"cordova-plugin-console\" in config.xml. Adding it to the project\nInstalling \"cordova-plugin-console\" for ios\nAdding cordova-plugin-console to package.json\nSaved plugin info for \"cordova-plugin-console\" to config.xml\nDiscovered plugin \"cordova-plugin-device\" in config.xml. Adding it to the project\nInstalling \"cordova-plugin-device\" for ios\nAdding cordova-plugin-device to package.json\nSaved plugin info for \"cordova-plugin-device\" to config.xml\nDiscovered plugin \"cordova-plugin-splashscreen\" in config.xml. Adding it to the project\nInstalling \"cordova-plugin-splashscreen\" for ios\nAdding cordova-plugin-splashscreen to package.json\nSaved plugin info for \"cordova-plugin-splashscreen\" to config.xml\nDiscovered plugin \"cordova-plugin-statusbar\" in config.xml. Adding it to the project\nInstalling \"cordova-plugin-statusbar\" for ios\nAdding cordova-plugin-statusbar to package.json\nSaved plugin info for \"cordova-plugin-statusbar\" to config.xml\nDiscovered plugin \"cordova-plugin-whitelist\" in config.xml. Adding it to the project\nInstalling \"cordova-plugin-whitelist\" for ios\nAdding cordova-plugin-whitelist to package.json\nSaved plugin info for \"cordova-plugin-whitelist\" to config.xml\nDiscovered plugin \"ionic-plugin-keyboard\" in config.xml. Adding it to the project\nInstalling \"ionic-plugin-keyboard\" for ios\nAdding ionic-plugin-keyboard to package.json\nSaved plugin info for \"ionic-plugin-keyboard\" to config.xml\n--save flag or autosave detected\nSaving ios@~4.4.0 into config.xml file ...\n\u2714 Copying default image resources into .\/resources\/ios - done!\n\n&gt; cordova platform add android --save\n\u2714 Running command - done!\nUsing cordova-fetch for cordova-android@~6.2.2\nAdding android project...\nCreating Cordova project for the Android platform:\n    Path: platforms\/android\n    Package: io.ionic.starter\n    Name: MyApp\n    Activity: MainActivity\n    Android target: android-25\nSubproject Path: CordovaLib\nAndroid project created with cordova-android@6.2.3\nInstalling \"cordova-plugin-console\" for android\nInstalling \"cordova-plugin-device\" for android\nInstalling \"cordova-plugin-splashscreen\" for android\nInstalling \"cordova-plugin-statusbar\" for android\nInstalling \"cordova-plugin-whitelist\" for android\n\n               This plugin is only applicable for versions of cordova-android greater than 4.0. If you have a previous platform version, you do *not* need this plugin since the whitelist will be built in.\n\nInstalling \"ionic-plugin-keyboard\" for android\n--save flag or autosave detected\nSaving android@~6.2.3 into config.xml file ...\n\u2714 Copying default image resources into .\/resources\/android - done!\n<\/code><\/pre>\n<p>After this, the <code>ionic cordova resources<\/code> command should work.<\/p>\n<p>From the output, you can see that 48 images were created and hopefully now you realize how much time this saved. All the needed configuration regarding the icons and splash screens was generated by Ionic and placed in the <strong>config.xml<\/strong> file.<\/p>\n<p>It&#8217;s worth noting that you will not see the icon nor the splash screen when using the browser testing or Ionic View testing (discussed in more detail in the <a href=\"#\">How to use Ionic.io cloud service to share our application with other users without going through the app store<\/a> section below). Instead, you will only see these once you deploy them to the actual physical device or the emulator (which we&#8217;ll cover in the <a href=\"#\">How to test our application on the real physical devices and emulators<\/a> section below).<\/p>\n<blockquote><p>\n  \u26a0\ufe0f You can add an iOS platform if you&#8217;re developing on a Windows machine, and <code>ionic cordova resources<\/code> command will generate icons and splash screens for it. However, keep in mind that <strong>you will not be able to build the project for iOS on your Windows machine<\/strong>. Instead, you&#8217;ll need a Mac computer to do so. We&#8217;ll cover building the app in more detail in the <a href=\"#\">How to test our application on the real physical devices and emulators<\/a> section below.\n<\/p><\/blockquote>\n<h2>How to implement Google AdMob ads<\/h2>\n<p>There are multiple ways you can earn money with your app these days and here are just a few:<\/p>\n<ul>\n<li><strong>Paid app<\/strong> &#8211; set a price for your app directly on the App\/Play Store that users need to pay before downloading your app<\/li>\n<li><strong>Freemium<\/strong> &#8211; give the app for free but charge for in-app purchases like adding some extra features (think more gold or faster production in game apps)<\/li>\n<li><strong>Ad-based<\/strong> &#8211; show ads inside your application. Potentially offer the in-app purchase to remove the ads<\/li>\n<\/ul>\n<p>Here we&#8217;re going to cover the Ad-based monetization option where I&#8217;ll show you how to add Google AdMob ads to our calculator application. There are two parts to implementing Google AdMob ads to an Ionic project, and I broke them into <strong>AdMob settings<\/strong> and <strong>Ionic settings<\/strong>.<\/p>\n<h3>AdMob settings<\/h3>\n<p>Let&#8217;s start with AdMob settings:<\/p>\n<ol>\n<li>Sign in\/Sign up for AdMob at <a href=\"https:\/\/www.google.com\/admob\/\">https:\/\/www.google.com\/admob\/<\/a><\/li>\n<li>Click the <strong>Apps<\/strong> and then <strong>ADD APP<\/strong> button:<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/QVyB7xP.png\" alt=\"\" \/><\/p>\n<ol>\n<li>Since our app is not published yet we will click the <strong>No<\/strong> button:<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/0Gv0dMe.png\" alt=\"\" \/><\/p>\n<ol>\n<li>Fill in the app name and platform and click the <strong>ADD<\/strong> button:<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/6lvQBKD.png\" alt=\"\" \/><\/p>\n<ol>\n<li>Save the App ID somewhere and proceed to create the Ad unit<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/RtiQyeP.png\" alt=\"\" \/><\/p>\n<ol>\n<li>Select Banner Ad format:<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/zRG8SgJ.png\" alt=\"\" \/><\/p>\n<ol>\n<li>Configure the adds type, size, placement, style, name:<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/pQYT4uG.png\" alt=\"\" \/><\/p>\n<ol>\n<li>You can read additional info on how to implement GA and AdMob, but for now, let&#8217;s just click Done:<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/kbZY18b.png\" alt=\"\" \/><\/p>\n<ol>\n<li>You will now see the following similar screen:<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/MujS4pC.png\" alt=\"\" \/><\/p>\n<p>The most important thing to note here is this <strong>Ad unit ID<\/strong>, which in my test case is <strong>ca-app-pub-7957971173858308\/5068937357<\/strong>. Make a note of this string as it&#8217;s the most important part of this setting. <em>You can click on the copy to clipboard button and paste it as a comment (for now) in your app.<\/em><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/6f1MO7a.png\" alt=\"\" \/><\/p>\n<ol>\n<li>Create as much Ad units as you may need (for each platform[iOS, Android] and ad format [Banner, Interstitial, etc.]). In my case, I just created the additional Interstitial Ad and will use them on both iOS and Android devices for this demo.<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/6qb2dum.png\" alt=\"\" \/><\/p>\n<h3>Ionic settings<\/h3>\n<p>Those of you familiar with Ionic 1 know that you can add any plugin to your Ionic project thanks to the project called <a href=\"http:\/\/ngcordova.com\/\">ngCordova<\/a>. For Ionic 3, there&#8217;s the same thing called <a href=\"https:\/\/ionicframework.com\/docs\/native\/\">Ionic Native<\/a>.<\/p>\n<p>Ionic Native is a TypeScript wrapper for Cordova\/PhoneGap plugins that makes it easy to add any native functionality that you may need into your Ionic app. Ionic Native wraps the plugin callbacks in a Promise or an Observable, providing a common interface for all plugins and ensuring that native events trigger change detection in Angular.<\/p>\n<p>Navigate to the root of the application with your Terminal\/Command prompt and execute the following command to add the <a href=\"https:\/\/ionicframework.com\/docs\/native\/admob-pro\/\">cordova-plugin-admobpro<\/a> plugin:<\/p>\n<p><code>ionic cordova plugin add cordova-plugin-admobpro<\/code><\/p>\n<p>You should see the following output after running the command:<\/p>\n<pre><code>&gt; cordova plugin add cordova-plugin-admobpro --save\n\u2714 Running command - done!\nInstalling \"cordova-plugin-admobpro\" for android\nInstalling \"cordova-plugin-extension\" for android\nSubproject Path: CordovaLib\nInstalling \"cordova-plugin-admobpro\" for ios\nPlugin dependency \"cordova-plugin-extension@1.5.1\" already fetched, using that version.\nInstalling \"cordova-plugin-extension\" for ios\nAdding cordova-plugin-admobpro to package.json\nSaved plugin info for \"cordova-plugin-admobpro\" to config.xml\n<\/code><\/pre>\n<p>Additionally, you also need to run this command:<\/p>\n<p><code>npm install --save @ionic-native\/admob-pro<\/code><\/p>\n<p>which, if completed successfully, will only output something like <code>added 1 package in 4.443s<\/code> to the console.<\/p>\n<p>You need to add this second command as well because this installs some files needed by TypeScript.<\/p>\n<blockquote><p>\n  \u26a0\ufe0f At this point, depending on the version of Ionic CLI that you have you may need to add a platform by executing: <code>ionic cordova platform add ios<\/code> or <code>ionic cordova platform add android<\/code> depending on the platform you&#8217;re trying to build for. You have to execute that if the command <code>ionic cordova platform ls<\/code> shows that you don&#8217;t have any installed platforms on the current project:<\/p>\n<pre><code>\u2192 ionic cordova platform ls\n\u2714 cordova platform ls - done!\nInstalled platforms:\nAvailable platforms: \n android ~6.2.2\n blackberry10 ~3.8.0 (deprecated)\n browser ~4.1.0\n ios 4.4.0\n osx ~4.0.1\n webos ~3.7.0\n<\/code><\/pre>\n<p>  If everything is fine with running <code>ionic cordova platform add ios<\/code> you will see an output like this:<\/p>\n<pre><code>Using cordova-fetch for cordova-ios@~4.4.0\nAdding ios project...\nCreating Cordova project for the iOS platform:\n    Path: platforms\/ios\n    Package: io.ionic.starter\n    Name: MyApp\niOS project created with cordova-ios@4.4.0\nInstalling \"cordova-plugin-admobpro\" for ios\nInstalling \"cordova-plugin-extension\" for ios\nDiscovered plugin \"cordova-plugin-console\" in config.xml. Adding it to &gt; the project\nInstalling \"cordova-plugin-console\" for ios\nAdding cordova-plugin-console to package.json\nSaved plugin info for \"cordova-plugin-console\" to config.xml\nDiscovered plugin \"cordova-plugin-device\" in config.xml. Adding it to &gt; the project\nInstalling \"cordova-plugin-device\" for ios\nAdding cordova-plugin-device to package.json\nSaved plugin info for \"cordova-plugin-device\" to config.xml\nDiscovered plugin \"cordova-plugin-splashscreen\" in config.xml. Adding &gt; it to the project\nInstalling \"cordova-plugin-splashscreen\" for ios\nAdding cordova-plugin-splashscreen to package.json\nSaved plugin info for \"cordova-plugin-splashscreen\" to config.xml\nDiscovered plugin \"cordova-plugin-statusbar\" in config.xml. Adding it &gt; to the project\nInstalling \"cordova-plugin-statusbar\" for ios\nAdding cordova-plugin-statusbar to package.json\nSaved plugin info for \"cordova-plugin-statusbar\" to config.xml\nDiscovered plugin \"cordova-plugin-whitelist\" in config.xml. Adding it &gt; to the project\nInstalling \"cordova-plugin-whitelist\" for ios\nAdding cordova-plugin-whitelist to package.json\nSaved plugin info for \"cordova-plugin-whitelist\" to config.xml\nDiscovered plugin \"ionic-plugin-keyboard\" in config.xml. Adding it to &gt; the project\nInstalling \"ionic-plugin-keyboard\" for ios\nAdding ionic-plugin-keyboard to package.json\nSaved plugin info for \"ionic-plugin-keyboard\" to config.xml\n--save flag or autosave detected\nSaving ios@~4.4.0 into config.xml file ...\n\u2714 Copying default image resources into .\/resources\/ios - done!\n<\/code><\/pre>\n<\/blockquote>\n<p>Btw, there is also a <a href=\"https:\/\/ionicframework.com\/docs\/native\/admob-free\/\">free version<\/a> of the AdMob Pro plugin. But, honestly, if you really start making money with your app, this will be a minor expense. <em>Besides, if you&#8217;re having problems giving back to the actual plugin through which you&#8217;re making money then my dear padawan you have yet much to learn&#8230;<\/em> ?<\/p>\n<p>Now, let&#8217;s add this plugin to our app&#8217;s NgModule. In the <code>src\/app\/app.module.ts<\/code> file import AdmobPro:<\/p>\n<p><code>import { AdMobPro } from '@ionic-native\/admob-pro';<\/code><\/p>\n<p>and then add it to the Providers array. The whole contents of the <code>src\/app\/app.module.ts<\/code> file should now looks like this:<\/p>\n<pre><code>import { NgModule, ErrorHandler } from '@angular\/core';\nimport { BrowserModule } from '@angular\/platform-browser';\nimport { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';\nimport { MyApp } from '.\/app.component';\nimport { CalculatorPage } from '..\/pages\/calculator\/calculator';\n\n\nimport { StatusBar } from '@ionic-native\/status-bar';\nimport { SplashScreen } from '@ionic-native\/splash-screen';\nimport { AdMobPro } from '@ionic-native\/admob-pro';\n\n@NgModule({\n    declarations: [\n        MyApp,\n        CalculatorPage\n    ],\n    imports: [\n        BrowserModule,\n        IonicModule.forRoot(MyApp)\n    ],\n    bootstrap: [IonicApp],\n    entryComponents: [\n        MyApp,\n        CalculatorPage\n    ],\n    providers: [\n        StatusBar,\n        SplashScreen,\n        AdMobPro,\n        { provide: ErrorHandler, useClass: IonicErrorHandler }\n    ]\n})\nexport class AppModule { }\n<\/code><\/pre>\n<p>Now I&#8217;m going to show you the final content of the <code>src\/pages\/calculator\/calculator.ts<\/code> file and will explain what was changed step by step:<\/p>\n<pre><code>import { Component } from '@angular\/core';\nimport { NavController } from 'ionic-angular';\nimport { AlertController } from 'ionic-angular';\n\nimport { AdMobPro } from '@ionic-native\/admob-pro';\nimport { Platform } from 'ionic-angular';\n\n@Component({\n    selector: 'page-calculator',\n    templateUrl: 'calculator.html'\n})\nexport class CalculatorPage {\n    constructor(public navCtrl: NavController, private alertCtrl: AlertController, private admob: AdMobPro, private platform: Platform) {\n        this.platform.ready().then(() =&gt; {\n            var admobid = {\n                banner: 'ca-app-pub-7957971173858308\/5068937357',\n                interstitial: 'ca-app-pub-7957971173858308\/5667703151'\n            };\n\n            this.admob.createBanner({\n                adId: admobid.banner,\n                isTesting: true,\n                autoShow: true,\n                position: this.admob.AD_POSITION.BOTTOM_CENTER\n            })\n\n            this.admob.prepareInterstitial({\n                adId: admobid.interstitial,\n                isTesting: true,\n                autoShow: false\n            })\n        });\n    }\n\n    result = '';\n    counter = 1;\n\n    showInterstitialAd() {\n        if (AdMobPro) {\n            this.admob.showInterstitial();\n        }\n    }\n\n    btnClicked(btn) {\n        if (btn == 'C') {\n            this.result = '';\n        }\n        else if (btn == '=') {\n            if (this.result == '') {\n                return;\n            }\n\n            try {\n                this.result = eval(this.result).toFixed(2);\n\n                if (this.counter++ == 5) {\n                    this.showInterstitialAd();\n                    this.counter = 0;\n                }\n            } catch (error) {\n                this.showAlert();\n                this.result = '';\n            }\n        }\n        else {\n            this.result += btn;\n        }\n    }\n\n    showAlert() {\n        this.alertCtrl.create({\n            title: 'Malformed input',\n            subTitle: 'Ooops, please try again...',\n            buttons: ['Dismiss']\n        }).present();\n    }\n}\n<\/code><\/pre>\n<p>First, we added the imports:<\/p>\n<pre><code>import { AdMobPro } from '@ionic-native\/admob-pro';\nimport { Platform } from 'ionic-angular';\n<\/code><\/pre>\n<p>Then, via the constructor we pulled in the Platform and AdMobPro:<\/p>\n<pre><code>constructor(public navCtrl: NavController, private alertCtrl: AlertController, private admob: AdMobPro, private platform: Platform) { }\n<\/code><\/pre>\n<p>Then we wrapped everything in the <code>platform.ready()<\/code> promise. This is the <strong>most important<\/strong> part of the code! If you wouldn&#8217;t do that, it could happen that your app would start up and the plugins would still not be properly set up, and you wouldn&#8217;t see the ads displayed.<\/p>\n<p>But then again, sometimes you would, and this is what it would make it a nightmare to debug. This is a very common issue that I&#8217;ve seen even back from Ionic 1 when answering the questions on <a href=\"https:\/\/stackoverflow.com\/users\/534755\/nikola?tab=answers\">StackOverflow<\/a>. So, you may want to keep an ?\ufe0f on the fact that you need to wrap any plugin calls inside the <code>platform.ready()<\/code> promise, as that way you&#8217;ll be sure that all of the plugins have loaded before you&#8217;ll use them.<\/p>\n<p>The code that&#8217;s executed after the promise resolves sets up our <code>admobid<\/code> object with <code>banner<\/code> and <code>interstitial<\/code> properties. Then we&#8217;re calling the <code>createBanner<\/code> and <code>prepareInterstitial<\/code> functions on the injected <code>admob<\/code> object. Note that the banner is set to show automatically when the app loads (<code>autoShow: true<\/code>) and the interstitial isn&#8217;t. Also, note that we&#8217;ve set the position of the banner ad to the bottom:<\/p>\n<pre><code>this.platform.ready().then(() =&gt; {\n    var admobid = {\n        banner: 'ca-app-pub-7957971173858308\/5068937357',\n        interstitial: 'ca-app-pub-7957971173858308\/5667703151'\n    };\n\n    this.admob.createBanner({\n        adId: admobid.banner,\n        isTesting: true,\n        autoShow: true,\n        position: this.admob.AD_POSITION.BOTTOM_CENTER\n    })\n\n    this.admob.prepareInterstitial({\n        adId: admobid.interstitial,\n        isTesting: true,\n        autoShow: false\n    })\n});\n<\/code><\/pre>\n<p>Then we added the <code>showshowInterstitialAdAd<\/code> function, which shows the Interstitial ad:<\/p>\n<pre><code>showInterstitialAd() {\n    if (AdMobPro) {\n        this.admob.showInterstitial();\n    }\n}\n<\/code><\/pre>\n<p>Of course, at this point, change the <code>adId<\/code> variable to your <code>admob_key<\/code> which you obtained in the first part (step 9). Also, when you&#8217;ll be publishing your app, don&#8217;t forget to change the <code>isTesting<\/code> variable to <code>false<\/code>. <em>Don&#8217;t worry, I&#8217;ll remind you when we get to that part.<\/em><\/p>\n<blockquote><p>\n  ? If you run into any problems with this, just ping in the comments, and I&#8217;ll do my best to help you.\n<\/p><\/blockquote>\n<p>One common thing that you might have to do for <strong>Android<\/strong> is to install some extras via the Android SDK manager. To do so open Android Studio and select <code>Configure-&gt;SDK Manager<\/code>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/i4DL8zk.png\" alt=\"\" \/><\/p>\n<p>Make sure you have installed the packages marked as <strong>Installed<\/strong> on the image below (usually, those are <strong>Google Billing Library<\/strong> and <strong>Google Play services<\/strong>):<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/dcM2rDs.png\" alt=\"\" \/><\/p>\n<p>For more information about the Android SDK manager, take a look at the section about <a href=\"#\">How to test our application on the real physical devices and emulators<\/a> futher in the post.<\/p>\n<h3>What kind of an ad should you show?<\/h3>\n<p>This plugin&#8217;s documentation states an interesting fact that it&#8217;s strongly recommended to use the Interstitial ad type because it brings more than 10 times profit than the banner Ad. Here&#8217;s the table from the <a href=\"https:\/\/github.com\/floatinghotpot\/cordova-admob-pro#tips\">official documentation<\/a>:<\/p>\n<table>\n<thead>\n<tr>\n<th>Ad Format<\/th>\n<th>Banner<\/th>\n<th>Interstitial<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Click Rate<\/td>\n<td>&lt; 1%<\/td>\n<td>3-15%<\/td>\n<\/tr>\n<tr>\n<td>RPM (1k impressions)<\/td>\n<td>0.5$ &#8211; 4$<\/td>\n<td>10-50$<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<blockquote><p>\n  Banner ad is the small add that is usually placed in the bottom of the screen, whereas Interstitial ads are full-screen ads that cover the interface of their host app. Therefore, you may rather want to opt for this kind of an ad instead for the Banner one.\n<\/p><\/blockquote>\n<p>It&#8217;s important to note that there&#8217;s probably no exact formula here on when to show the Interstitial Ad, but there are some best practices, and this is what Google has to say about it:<\/p>\n<blockquote><p>\n  Interstitial ads work best in apps with natural transition points. The conclusion of a task within an app, like sharing an image or completing a game level, creates such a point. Because the user is expecting a break in the action, it&#8217;s easy to present an interstitial without disrupting their experience. Make sure you consider at which points in your app&#8217;s workflow you&#8217;ll display interstitials, and how the user is likely to respond.\n<\/p><\/blockquote>\n<p>You can learn a bit more about it <a href=\"https:\/\/developers.google.com\/admob\/android\/interstitial\">here<\/a>.<\/p>\n<p>Anyways, as you saw in my demo code above, I&#8217;ve opted for showing the banner ad all the time in the bottom of the screen, and I&#8217;m showing the interstitial ad every 5th time the user clicks the <code>=<\/code> button. You can tweak this any way you like in your app, but please remember the points mentioned above about best practices.<\/p>\n<h2>How to use Ionic.io cloud service to share our application with other users without going through the app store<\/h2>\n<p>Having the ability to immediately get feedback on something that you&#8217;re working on, without having to install the app manually on your client&#8217;s devices or waiting for the App Store\/Play Store approval is indispensable for constant feedback loop which is crucial in rapid application development. <em>This is something that Eric Ries stresses a lot in his book <a href=\"http:\/\/www.nikola-breznjak.com\/blog\/books\/the-lean-startup-eric-ries\/\">The Lean Startup<\/a><\/em>.<\/p>\n<p>In Ionic, this is easier than you may have thought. All you have to do is create the account on <a href=\"https:\/\/apps.ionic.io\">https:\/\/apps.ionic.io<\/a> and after that in your Terminal\/Command prompt in the root of the project just type the following command:<\/p>\n<p><code>ionic upload<\/code><\/p>\n<p>This will prompt you to login with your username and password combination which you created in the previous step. After successful login, the app will be uploaded to the Ionic.io cloud service and you will be able to view the app through an app called <a href=\"http:\/\/view.ionic.io\/\">Ionic View<\/a>, which you can download for free on your smartphone from the App Store\/Play Store.<\/p>\n<p>The output of the above command is short:<\/p>\n<pre><code>[INFO] Running app-scripts build: \n\n[09:55:39]  build dev started ... \n[09:55:39]  clean started ... \n[09:55:39]  clean finished in 2 ms \n[09:55:39]  copy started ... \n[09:55:39]  transpile started ... \n[09:55:42]  transpile finished in 2.30 s \n[09:55:42]  preprocess started ... \n[09:55:42]  deeplinks started ... \n[09:55:42]  deeplinks finished in 4 ms \n[09:55:42]  preprocess finished in 5 ms \n[09:55:42]  webpack started ... \n[09:55:42]  copy finished in 2.44 s \n[09:55:47]  webpack finished in 5.10 s \n[09:55:47]  sass started ... \n[09:55:48]  sass finished in 1.39 s \n[09:55:48]  postprocess started ... \n[09:55:48]  postprocess finished in 4 ms \n[09:55:48]  lint started ... \n[09:55:48]  build dev finished in 8.84 s \n&gt; ionic cordova prepare\n&gt; cordova prepare\n\u2714 Running command - done!\n\n[09:55:50]  lint finished in 1.87 s \n\u2714 Requesting snapshot upload - done!\n\u2714 Uploading snapshot - done!\n[OK] Uploaded snapshot 19a5c87e-92aa-4757-b2c0-1c24e7ee9657!\n<\/code><\/pre>\n<p>And, as stated in the output, to share your app with a client or a friend, without first having to go through the App Store\/Play Store, go to <a href=\"https:\/\/apps.ionic.io\">https:\/\/apps.ionic.io<\/a> and add the testers email under the <code>Settings-&gt;Collaborators<\/code> section:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/zFEikV0.png\" alt=\"\" \/><\/p>\n<p>User will receive an email which will guide him through the setup:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/MhDL7Fn.png\" alt=\"\" \/><\/p>\n<blockquote><p>\n  \u26a0\ufe0f Those of you coming from Ionic 1 and being used to the <code>ionic share EMAIL<\/code> command, you&#8217;ll get the following error message if you run it:<br \/>\n  ionic share some.email@mail.com<\/p>\n<pre><code>[ERROR] ionic share has been removed as of CLI 3.0.\nThe functionality now exists in the Ionic Dashboard: https:\/\/apps.ionic.io\n<\/code><\/pre>\n<\/blockquote>\n<p>If you&#8217;ll get an error like this:<\/p>\n<blockquote><p>\n  [ERROR] Your project file (.\/ionic.config.json) does not contain &#8216;app_id&#8217;. Run ionic link.\n<\/p><\/blockquote>\n<p>Then execute the command <code>ionic link<\/code> and choose the <code>Create new app<\/code> option in the terminal. That will bring you to the web interface where you have to enter the name of your app and click the <code>Create App<\/code> button:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/nbw0K3W.png\" alt=\"\" \/><\/p>\n<p>Once the app is created you&#8217;ll see something like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/yzndfCE.png\" alt=\"\" \/><\/p>\n<p>Now go back to your Terminal and run <code>ionic link<\/code> again and choose the name your app. You should see an output similar to this:<\/p>\n<pre><code>\u2714 Looking up your apps - done!\n? Which app would you like to link SuperSimpleCalculator (dec5230f)\n&gt; ionic config set app_id dec5230f\n[OK] app_id set to dec5230f in .\/ionic.config.json!\n[OK] Project linked with app dec5230f!\n<\/code><\/pre>\n<p>Now you can rerun the <code>ionic upload<\/code> command and get an output that the snapshot of your app has been uploaded.<\/p>\n<p>Once your client\/tester\/friend gets the email for being a Collaborator, he will be guided through setting up Ionic View and viewing your app.<\/p>\n<p>However, there&#8217;s one more way for your client\/friend to try out the app. First, tell them to download the <code>Ionic View<\/code> app from the App Store\/Play Store:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/83VYnPu.jpg\" alt=\"\" \/><\/p>\n<p>They will have to sign up (it&#8217;s free):<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/hquQZiP.png\" alt=\"\" \/><\/p>\n<p>And once they&#8217;re logged in, they have to click the <code>PREVIEW A SHARED APP<\/code> button:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/mpwVTyb.png\" alt=\"\" \/><\/p>\n<p>At this point, they will have to enter your App Id which you&#8217;ll have to send them (Slack, Email, Messenger, choose your ?). You can find your id in the <a href=\"https:\/\/apps.ionic.io\/apps\/\">Ionic dashboard<\/a>. In my case the id is <code>dec523f<\/code>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/aeTiNRk.png\" alt=\"\" \/><\/p>\n<p>They have to enter this id in the form and click the <code>LOAD APP<\/code> button:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/xP3gdLs.png\" alt=\"\" \/><\/p>\n<p>They will get the following screen with instructions on how to use the app:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/HF38QpU.png\" alt=\"\" \/><\/p>\n<p>You will notice that we will not see ads in this version because Ionic View does not support the AdMob plugin:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/SsrW20K.png\" alt=\"\" \/><\/p>\n<p>Suffice to say; you dear reader can also try this out via your own Ionic View app.<\/p>\n<h2>How to test our application on the real physical devices and emulators<\/h2>\n<p>If you run the application (to which you added AdMob) in the browser, you will see few notices in your browser&#8217;s Console output that AdMob is not defined:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/kQCK5sj.png\" alt=\"\" \/><\/p>\n<p>Also, if you view the app in Ionic View, you will notice that no ads will show up. This is because <strong>Cordova plugins don&#8217;t work in the browser, nor in the Ionic View<\/strong>. Instead, they have to be tested on the real device or in an emulator (in iOS terminology the word <code>simulator<\/code> is used). Just for reference, there are <a href=\"http:\/\/docs.ionic.io\/tools\/view\/#supported-plugins\">some plugins<\/a> that work in the Ionic View.<\/p>\n<p>In this section, we&#8217;re going to show how to install the needed prerequisites and how to run our application in an simulator\/emulator and on the actual physical device for both iOS and Android.<\/p>\n<h3>iOS settings<\/h3>\n<p>The main tool for developing native iOS applications is <a href=\"https:\/\/developer.apple.com\/xcode\/\">Xcode<\/a>. Xcode is praise-worthily free for download, and it comes with a lot of simulators in which you can see how your app would look like on a real device.<\/p>\n<p>However, if you want to build and deploy iOS applications to the App Store, you need to have a <a href=\"http:\/\/www.apple.com\/mac\/\">Mac computer<\/a> since Xcode only works on their operating system. Yes, <strong>even if you&#8217;re using Ionic, you need to use Xcode<\/strong> to build the application for iOS.<\/p>\n<p>There are some ways around this, like for example with using a so-called <a href=\"http:\/\/www.hackintosh.com\/\">Hackintosh<\/a> computer, but honestly, from my experience, this is just not worth it.<\/p>\n<p>If you&#8217;re really anti-Apple ?, then you&#8217;ll be happy to know that there are services which allow you to <a href=\"http:\/\/www.macincloud.com\/\">rent a Mac in the cloud<\/a>, just for the time you need to build your application. Also, Ionic offers the so-called <a href=\"\">Package<\/a> service that allows you to build mobile apps for any supported platform even if you don\u2019t have a Mac. We won&#8217;t cover that here, but you can take a look at the <a href=\"https:\/\/docs.ionic.io\/services\/package\/\">official Package service<\/a> documentation.<\/p>\n<blockquote><p>\n  To <strong>publish an app<\/strong> in the App Store (or <strong>test it on your own iOS device<\/strong>) you&#8217;ll need to purchase the <em>Apple Developer Program<\/em> license which costs <strong>US $99 per year<\/strong>. You\u2019ll need to sign up at <a href=\"http:\/\/developer.apple.com\">http:\/\/developer.apple.com<\/a>, but don&#8217;t worry about this for now; we&#8217;ll cover all the steps in the next tutorial where I&#8217;ll guide you through the process of deploying the application for both the Apple&#8217;s App Store and Google&#8217;s Play Store.\n<\/p><\/blockquote>\n<h4>Installing the needed tools<\/h4>\n<p>As we&#8217;ve mentioned before, you need to install Xcode, and you can do that by opening up the App Store application on your Mac and search for Xcode. You install it like any other application by clicking on the download button and following the NextNextNext type of installation.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/pERZ1hO.png\" alt=\"\" \/><\/p>\n<p>After the installation is finished, open up Xcode, and navigate to <code>Xcode -&gt; Preferences -&gt; Downloads<\/code> tab. Here you can download the latest version of the Simulator available. In my case, at the time of this writing, the latest version is iOS 11.0 Simulator, as you can see on the image below:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/Vocnyw1.png\" alt=\"\" \/><\/p>\n<p>Also, we need to install the ios-sim package with npm:<\/p>\n<p><code>npm install -g ios-sim<\/code><\/p>\n<h4>Running our application in a simulator<\/h4>\n<p>Now, to test our application in a simulator all we have to do is execute the following command:<\/p>\n<p><code>ionic cordova emulate ios<\/code><\/p>\n<p>After a bunch of cryptic messages you should see a Xcode simulator open up and show your awesome application along with a splash screen and ads:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/oGtFIad.png\" alt=\"\" \/><\/p>\n<blockquote><p>\n  \u26a0\ufe0f In case you get an error like this:<\/p>\n<pre><code>** BUILD SUCCEEDED **\nError: Cannot read property 'replace' of undefined\n[ERROR] An error occurred while running cordova emulate ios (exit code 1).\n<\/code><\/pre>\n<p>  Then execute the following command (don&#8217;t use sudo if on Windows):<\/p>\n<pre><code>cd platforms\/ios\/cordova\/node_modules\/ &amp;&amp; sudo npm install ios-sim@latest\n<\/code><\/pre>\n<p>  After this repeat the emulate command and all should be well.<\/p>\n<p>  <em>Of course, run the <code>ionic cordova emulate ios<\/code> command in the root directory of the project, not in the <code>\/platforms\/ios\/cordova\/node_modules<\/code> folder!<\/em>\n<\/p><\/blockquote>\n<p>If you test the app by doing five calculations, then after the fifth time you press the equals button <code>=<\/code> the Interstitial ad will appear, as shown in the image below:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/MVeUMpw.png\" alt=\"\" \/><\/p>\n<p>If you exit the simulator back to the home screen (by pressing `Command (\u2318) + Shift + H) you will see the application&#8217;s icon:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/ciMninE.png\" alt=\"\" \/><\/p>\n<p>When you&#8217;re testing your application in a browser with <code>ionic lab<\/code> you have that great live reload feature. You can have that too in the simulator if you run the simulator with the extra <code>-l<\/code> flag. If you also want to see the <code>console.log<\/code> output, as you would see it in the browser, then you have to add the <code>\u2013c<\/code> flag:<\/p>\n<pre><code>ionic cordova emulate ios -lc\n<\/code><\/pre>\n<blockquote><p>\n  Since we need to have an Apple Developer account to run the application on our physical phone device, we will leave this for our next tutorial where we&#8217;ll also show how to deploy the application to the actual App Store.<\/p>\n<p>  \u26a0\ufe0f At the time of writing this you can see in the updated screenshots of the iOS 11 simulator, the app isn&#8217;t iOS 11 ready. However, anyone that will be following this tutorial anew and will have <code>ionic<\/code> and <code>cordova<\/code> npm packages up to date, will not have this problem, as the Ionic team fixed everything in time for the iPhone X release. For more information, see the <a href=\"https:\/\/blog.ionic.io\/ios-11-checklist\/\">official blog post<\/a>. For those of you who are maybe looking to update your Ionic 1 app to look nice on iPhone X, take a look at <a href=\"http:\/\/www.nikola-breznjak.com\/blog\/javascript\/ionic\/make-ionic-1-app-look-good-iphone-x\/\">this tutorial<\/a>.\n<\/p><\/blockquote>\n<h3>Android settings<\/h3>\n<p>There are no prerequisites for Android development regarding the operating systems; you can develop for Android on Mac, Linux, and Windows computers.<\/p>\n<p>Android provides some tools for developers that are available for free from their <a href=\"https:\/\/developer.android.com\/index.html\">website<\/a>.<\/p>\n<blockquote><p>\n  ? To publish an app in the Play Store you&#8217;ll need to purchase the <em>Developer Program<\/em> license which costs only <strong>US $25 one-time fee<\/strong>. You\u2019ll need to sign up at <a href=\"https:\/\/play.google.com\/apps\/publish\/signup\/\">https:\/\/play.google.com\/apps\/publish\/signup\/<\/a>, but as said before &#8211; don&#8217;t worry; we&#8217;ll cover all the steps in the next tutorial.\n<\/p><\/blockquote>\n<h4>Installing the needed tools<\/h4>\n<p>Download Android Studio from <a href=\"https:\/\/developer.android.com\/studio\/index.html\">https:\/\/developer.android.com\/studio\/index.html<\/a><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/L8FiYYp.png\" alt=\"\" \/><\/p>\n<p>The installation is a simple NextNextNext type of installation, but if you get stuck, they have great <a href=\"https:\/\/developer.android.com\/studio\/install.html\">official documentation<\/a>.<\/p>\n<p>Next, you need to set up the so-called <code>PATH<\/code> variable to point to the Android SDK tools. You can find the path by opening up the Android Studio, select the <code>Configure-&gt;SDK Manager<\/code> option and copy the <code>Android SDK Location<\/code>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/dcM2rDs.png\" alt=\"\" \/><\/p>\n<p>On Mac, you can set the <code>PATH<\/code> variable like this:<\/p>\n<p><code>export PATH=$PATH:\/Users\/nikola\/Library\/Android\/sdk\/tools\/<\/code>.<\/p>\n<p>You may want to put this line to your <code>.bash_profile<\/code> (or any related that you may have like <code>.zshrc<\/code>) file. For any further details about how to set the <code>PATH<\/code> variable, you can take a look at <a href=\"http:\/\/www.cyberciti.biz\/faq\/appleosx-bash-unix-change-set-path-environment-variable\/\">this tutorial<\/a>.<\/p>\n<p>As for <strong>Windows<\/strong>, the command would be:<\/p>\n<p><code>set PATH=%PATH%;C:\\Dev\\android-sdk\\tools<\/code><\/p>\n<blockquote><p>\n  \u26a0\ufe0f <em>To be honest, you may still encounter some errors while trying to get this to work and I&#8217;ve answered quite a few issues on StackOverflow. So, if you get stuck at this point, just drop me a line in the comments, and I&#8217;ll do my best to help.<\/em>\n<\/p><\/blockquote>\n<p>Once you&#8217;ve set the PATH variable correctly for your operating system, you can check if it&#8217;s OK by opening up your Terminal\/Command prompt and typing:<\/p>\n<p><code>android<\/code><\/p>\n<p>You should get an output similar to this one:<\/p>\n<pre><code>android\n*************************************************************************\nThe \"android\" command is deprecated.\nFor manual SDK, AVD, and project management, please use Android Studio.\nFor command-line tools, use tools\/bin\/sdkmanager and tools\/bin\/avdmanager\n*************************************************************************\nInvalid or unsupported command \"\"\n\nSupported commands are:\nandroid list target\nandroid list avd\nandroid list device\nandroid create avd\nandroid move avd\nandroid delete avd\nandroid list sdk\nandroid update sdk\n<\/code><\/pre>\n<blockquote><p>\n  You may get a message that you don&#8217;t have java tools installed:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/Xnr9ny5.png\" alt=\"\" \/><\/p>\n<p>  In that case, click the <code>More Info...<\/code> button and you&#8217;ll be directed to their website where you have to click on the <code>DOWNLOAD<\/code> button (make sure you click the JDK one): <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/MNc2bL1.png\" alt=\"\" \/> Then, on the next screen, click the <code>Accept License Agreement<\/code> and select your operating system:<br \/>\n  <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/AdjqTws.png\" alt=\"\" \/><br \/>\n  After the download run the .dmg file (on Mac OS) and finish the NextNextNext type of installation. If you&#8217;re on Windows, make appropriate choices for your OS.\n<\/p><\/blockquote>\n<p>Finally, you need to set up the SDK packages. For those of you who are in this field a bit longer, you&#8217;ll remember that you had to do everything via the Terminal\/Command prompt. Specifically, for this you had to enter:<\/p>\n<p><code>android sdk<\/code><\/p>\n<p>But, with the new version of the Android Studio, as you saw in the previous Terminal output, you don&#8217;t have to do that. The way you should open up the SDK Manager is by opening up Android Studio and then click on <code>Configure-&gt;SDK Manager<\/code>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/i4DL8zk.png\" alt=\"\" \/><\/p>\n<p>I recommend that you download just the most recent packages as shown on the image below. Most probably you&#8217;ll have everything installed except <strong>Google Play services<\/strong> and <strong>Google Play Billing Library<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/yUAQyTO.png\" alt=\"\" \/><\/p>\n<p>Make sure that you download only the platforms that you&#8217;ll need. On the image below, only the Android 7.1.1 (Nougat) version is installed:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/3FypyHO.png\" alt=\"\" \/><\/p>\n<p>Now run <code>ionic cordova build android<\/code>, and open the folder <code>platforms\/android\/<\/code> with Android Studio (click the <code>Open an existing Android Studio project<\/code> link\/button) and you should see something like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/tOM1Xwu.png\" alt=\"\" \/><\/p>\n<h4>Create a new emulator<\/h4>\n<p>You need to have an emulator on which you&#8217;ll run your Android app. To begin the process of adding it, click on the <code>Tools-&gt;Android-&gt;AVD Manager<\/code>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/7EQq7zZ.png\" alt=\"\" \/><\/p>\n<p>Click the <code>Create Virtual Device<\/code> button:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/sDroCiB.png\" alt=\"\" \/><\/p>\n<p>Choose a device:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/Bi8q7hS.png\" alt=\"\" \/><\/p>\n<p>Select the system image and click the <code>Next<\/code> button. If need be, first click on the <code>Download<\/code> link.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/UrQeVtn.png\" alt=\"\" \/><\/p>\n<p>On the final screen just click the <code>Finish<\/code> button and you should see the following screen which shows the summary of your virtual devices:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/MnqN1fM.png\" alt=\"\" \/><\/p>\n<h4>Run the app on the new emulator<\/h4>\n<p>Run <code>ionic cordova emulate android<\/code> and you should see an Android emulator start up and show you your app:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/xqDvwpV.png\" alt=\"\" \/><\/p>\n<h4>Run the app on the physical device<\/h4>\n<p>If you would like to run the application on your own Android device then you first have to run the following command to build the project:<\/p>\n<p><code>ionic cordova build android<\/code><\/p>\n<p>The last few lines of the output will be something like:<\/p>\n<pre><code>BUILD SUCCESSFUL\n\nTotal time: 1.557 secs\nBuilt the following apk(s): \n    \/Users\/nikola\/DEV\/Ionic3\/Ionic3_3rdTutorial\/platforms\/android\/build\/outputs\/apk\/android-debug.apk\n<\/code><\/pre>\n<p>To be able to test your application on your Android device, you have to enable the developer settings, and you can do that in few steps:<\/p>\n<ul>\n<li>Open the Settings view and scroll to <code>About Phone<\/code><\/li>\n<li>At the bottom of the About Phone view find a <code>Build Number<\/code> and tap on it seven times to enable the developer mode.<\/li>\n<li>After this you can go back to the <code>Settings<\/code> view, and you&#8217;ll see a new option called <code>Developer Options<\/code><\/li>\n<\/ul>\n<p>Now you have to enable the USB debugging, and you can do that in the next few steps:<\/p>\n<ul>\n<li>Select <code>Developer Options<\/code> item in the <code>Settings<\/code> view<\/li>\n<li>Scroll down until you see the USB debugging option<\/li>\n<li>Toggle it ON<\/li>\n<li>Now your device is set up for debugging, and when it&#8217;s connected to your computer you&#8217;ll be able to deploy the application to the device<\/li>\n<\/ul>\n<p>Now connect your device and execute the following command in your Termina\/Command prompt:<\/p>\n<p><code>ionic cordova run android<\/code><\/p>\n<p>Find the application in your application list and open it. You should see the ads at the bottom, and after the fifth calculation, you should see an Interstitial ad appear.<\/p>\n<p>\u26a0\ufe0f If for some reason the <code>ionic cordova run android<\/code> command wouldn&#8217;t work for you, you can always just copy the generated <code>.apk<\/code> file manually to your connected device (for example in the <code>Downloads<\/code> folder). After that open the <code>Downloads<\/code> folder on your phone with the file manager application that you use and open the <code>.apk<\/code> file that you pasted in. This way you&#8217;ll be prompted to install the application on your phone and then you&#8217;ll be able to find it in the programs list:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/9Fkfc6n.png\" alt=\"\" \/><\/p>\n<h2>Conclusion<\/h2>\n<p>In this tutorial, you&#8217;ve learned quite a few things. You learned how to polish the existing calculator application by improving the design and user experience. Next, you learned how to create icons and splash screen images automatically. Then, how to make money with your application by using Google AdMob ads. Also, how to share your application with other users without going through the app stores. Finally, you learned how to test your application on the real physical devices and emulators.<\/p>\n<p>In the next tutorial, I&#8217;m going to show you how to prepare the application for the Apple&#8217;s App Store and Google&#8217;s Play Store and finally, how to publish the application to both Apple&#8217;s App Store and Google&#8217;s Play Store.<\/p>\n<p>Until next time, keep on coding \u270c\ufe0f<\/p>\n<blockquote class=\"twitter-tweet\" data-width=\"550\">\n<p lang=\"en\" dir=\"ltr\">How to polish our existing <a href=\"https:\/\/twitter.com\/Ionicframework?ref_src=twsrc%5Etfw\">@ionicframework<\/a> 3 calculator application <a href=\"https:\/\/t.co\/uBmiwsyHps\">https:\/\/t.co\/uBmiwsyHps<\/a><\/p>\n<p>&mdash; Nikola Bre\u017enjak (@HitmanHR) <a href=\"https:\/\/twitter.com\/HitmanHR\/status\/941731421160218625?ref_src=twsrc%5Etfw\">December 15, 2017<\/a><\/p><\/blockquote>\n<p><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the third post in a series of posts which will teach you how to take advantage of your web development knowledge in building hybrid applications for&hellip;<\/p>\n","protected":false},"author":1,"featured_media":3848,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[56],"tags":[],"class_list":["post-3845","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ionic3"],"_links":{"self":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3845","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=3845"}],"version-history":[{"count":3,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3845\/revisions"}],"predecessor-version":[{"id":3850,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3845\/revisions\/3850"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media\/3848"}],"wp:attachment":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media?parent=3845"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/categories?post=3845"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/tags?post=3845"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}