Skip to content

Instantly share code, notes, and snippets.

@jnewman12
Last active February 23, 2017 08:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jnewman12/6ce2772195f36e0c0362198c8204f189 to your computer and use it in GitHub Desktop.
Save jnewman12/6ce2772195f36e0c0362198c8204f189 to your computer and use it in GitHub Desktop.
All Day Ionic

Intro to Ionic

ionic


Objectives

  • Understand the use case for Ionic
  • Identify the tech stack involved in creating ionic apps
  • create a basic ionic app

What is Ionic

  • Ionic is an HTML5 mobile app development framework targeted at building hybrid mobile apps. Hybrid apps are essentially small websites running in a browser shell in an app that have access to the native platform layer.
  • Hybrid apps have many benefits over pure native apps, specifically in terms of platform support, speed of development, and access to 3rd party code.

Ionic represents a something you might see as a developers in the mobile sphere, which is native vs hybrid

native vs hybrid

  • Think of Ionic as the front-end UI framework that handles all of the look and feel and UI interactions your app needs in order to be compelling.
  • Kind of like “Bootstrap for Native,” but with support for a broad range of common native mobile components, slick animations, and beautiful design.
  • Since Ionic is an HTML5 framework, it needs a native wrapper like Cordova or PhoneGap in order to run as a native app.

What is Phonegap and Cordova?

cordova vs phonegap

  • Both Apache cordova and Phonegap are frameworks for mobile application development.
  • Apache Cordova is a platform for building native mobile applications using HTML, CSS and JavaScript.
  • PhoneGap is an HTML5 app platform that allows you to use web technologies and get access to APIs and app stores to build native mobile applications.
  • PhoneGap is a distribution of Apache Cordova. You can think of Apache Cordova as the engine that powers PhoneGap, similar to how WebKit is the engine that powers Chrome or Safari.

Building Hybrid Apps

  • At its core, Ionic is just a web page running in an native app shell! That means we can use any kind of HTML, CSS, and Javascript we want. The only difference is, instead of creating a website that others will link to, we are building a self-contained application experience.
  • The bulk of an Ionic app will be written in HTML, Javascript, and CSS. Eager developers might also dig down into the native layer with custom Cordova plugins or native code, but it’s not necessary to get a great app.

Installing Ionic

  • Now that we know a little bit about Ionic, and why we might want to use it, we need to next set it up on our machines

Setting it up

  • You can develop Ionic apps on any operating system you prefer. In fact, Ionic has been developed at various times on Mac OS X, Linux, and Windows.
  • First, we will go and install the most recent version of Apache Cordova, which will take our app and bundle it into a native wrapper to turn it into a traditional native app.
  • To install Cordova we want to run

npm install -g cordova

Once we have cordova, we need to get ionic!

npm install -g ionic

Once we have Cordova and Ionic installed, we can move on to our app


Our First Ionic App

  • To get our feet wet with our first Ionic App, we're going to create a simple todo app before we move on to our more advanced application

  • let's CD into our workspace

  • to make a new app we run ionic start {appname} {template}

  • when making an ionic app, we get a couple different templates to generate from. Those commands are blank, tabs, and sidemenu

  • once you're inside your favorite workspace, run

    • ionic start ionic-todo blank
  • were using the blank template for simplicity in this example.

  • The command will generate a new project for us and also install some dependencies.

  • once this has ran, we can CD into our new folders, and let's check out the file structure

├── hooks                          // custom cordova hooks to execute on specific commands
├── platforms                      // iOS/Android specific builds will reside here
├── plugins                        // where your cordova/ionic plugins will be installed
├── resources                      // icon and splash screen
├── scss                           // scss code, which will output to www/css/
|── www                            // application - JS code and libs, CSS, images, etc.
     |---------css                 // customs styles
     |---------img                 // app images
     |---------js                  // angular app and custom JS
     |---------lib                 // third party libraries
     |---------index.html          // app master page        
├── bower.json                     // bower dependencies
├── config.xml                     // cordova configuration
├── gulpfile.js                    // gulp tasks
├── ionic.project                  // ionic configuration
├── package.json                   // node dependencies

  • the file structure and scaffolding reminds me of rails, and it gives us nice framework to work inside of. For the most part, we will be spending most of our time inside the www/ folder, which is where everything angular related lives

Configuring Platforms

As we discussed, Cordova gives you the power to write once and run on many platforms (iOS, Android, Blackberry, Windows, etc) but you have to explicitly tell Cordova (with Ionic) which platform should be included in a given project. For our Todo app, we will be trying with two platforms (iOS and Android).

ionic platform add ios

ionic platform add android

Previewing the App

  • We can preview our app in the browser using Ionic. This is not recommended though (about that later) but we can use it to preview
  • To see what our blank app looks like, run the below command in the CLI on the ionic-todo directory:

ionic serve

  • This command will open up a browser at http:localhost:8100.
  • The browser screen is too large to preview a mobile app and for that reason, Ionic added --lab as an option to running the app in the browser so as to preview the app better as it would be seen in Android and iOS.
  • But this view isn't too accurate. It's too big, we'd have to shrink it all the way and even then it'd still be ~50 pixels too wide
  • Ionic also gives us a lab option to simulate what it will look like on iOS and android
  • To run that comman, exit out of ionic serve, and re-run with

ionic serve --lab

  • This will also act as a live reload server, and any change we make in our app will be reflected in our server

Building Features

  • now that we have our conceptual overview, a scaffolded project, and some config set up, let's write some features
  • we are going to be building a simple to-do application to show that all Ionic is made of is Angular.js and some cool native stuff sprinkled on top

Ionic creates a bundle of Angular and required dependencies (angular-ui-router, angular-animate, angular-sanitize, etc) bundled in one file called ionic.bundle.js.

Before continuing, let us define some tasks we need to complete in our app so we don’t loose focus:

  • Setup Local Storage service to store todo data
  • Create a main controller to interact with our view
  • Update our index.html to work with the controller

Local Storage Service

  • Like we saw the other day, Local Storage allows us to store things inside a users browser to persist even after they have closed out of it.
  • From tokens, to id's, and other random data bits, we can use this to help us build mobile applications
  • Angular has a service written to wrap the Local Storage API called angular-local-storage.
  • Ionic uses bower to manage dependencies so installing all this kind of code is just like using Express

bower install angular-local-storage --save

  • The command will download and add angular-local-storage to our app libraries.
  • Now we just need to add it to our index.html
  • In your index.html, find where the ionic.bundle.js is and paste it right below (for me, that's line 27)
<script src="lib/angular-local-storage/dist/angular-local-storage.js"></script>
  • Next, we just need to tell our angular app local storage is a dependency and inject it inside our app
  • Inside our app.js, we need to add our Local Storage Module inside our angular.module call like this

angular.module('starter', ['ionic', 'LocalStorageModule'])

  • When working with LocalStorage, it is a good practice to add a prefix to our stored entities so as avoid being overwritten in future. - Let's add a config angular block to set the Local Storage prefix
.config(function (localStorageServiceProvider) {
  localStorageServiceProvider.setPrefix('ionic-todo');
})

Controllers

Our controller will be serving as the middle man between our Local Storage data and our view www/index.html. Let us first create a structure of the controller just below our config block in app.js:

.controller('main', function ($scope, $ionicModal, localStorageService) {
  //store the entities name in a variable
  var taskData = 'task';

  //initialize the tasks scope with empty array
  $scope.tasks = [];

  //initialize the task scope with empty object
  $scope.task = {};

  //configure the ionic modal before use
  $ionicModal.fromTemplateUrl('new-task-modal.html', {
    scope: $scope,
    animation: 'slide-in-up'
  }).then(function (modal) {
    $scope.newTaskModal = modal;
  });

  $scope.getTasks = function () {
    //fetches task from local storage
  }

  $scope.createTask = function () {
    //creates a new task
  }

  $scope.removeTask = function () {
    //removes a task
  }

  $scope.completeTask = function () {
    //updates a task as completed
  }
})

Notice how we have injected localStorageService in the controller so as to help us interact with Local Storage from the controller. We also injected $ionicModal service to help us create tasks from a modal.

Now, we need to tell the index.html which controller to use and run getTasks() when the app starts:

<body ng-app="starter" ng-controller="main" ng-init="getTasks()"> 
</body>

Filling out our methods

  • Now that we all have that, let's add our getTasks() function
$scope.getTasks = function () {
  //fetches task from local storage
  if (localStorageService.get(taskData)) {
    $scope.tasks = localStorageService.get(taskData);
  } else {
    $scope.tasks = [];
  }
}

So we have a way to grab all of these tasks. Let's now create a new one

$scope.createTask = function () {
  //creates a new task
  $scope.tasks.push($scope.task);
  localStorageService.set(taskData, $scope.tasks);
  $scope.task = {};
  //close new task modal
  $scope.newTaskModal.hide();
}

Great! We can grab all tasks, and create one! Now, let's add a way to delete a task we don't need any more

$scope.removeTask = function (index) {
  //removes a task
  $scope.tasks.splice(index, 1);
  localStorageService.set(taskData, $scope.tasks);
}

Like we have seen in our other array examples, we are finding an item in an array based on it's index, and removing it with splice. For our last method, lets give our app a way to update whether a task is completed or not

$scope.completeTask = function (index) { 
  //updates a task as completed 
  if (index !== -1) {
    $scope.tasks[index].completed = true; 
  } 

  localStorageService.set(taskData, $scope.tasks); 
}

Our View

  • So far, we have our Model (Local Storage Data), and we have our controller. Now we just need to add our view.
  • First, let's side track ourselves and take a look at some ionic docs
  • For a clean display of tasks, let us use ionic’s card component to display our tasks
  • In our index.html, inside our ion-content tag, let's add the following
<div class="list card" ng-repeat="task in tasks track by $index">
  <div class="item item-divider">
    <span ng-bind="task.title"></span>
  </div>

  <div class="item item-body">
    <strong>Title: <span ng-bind="task.title"></span></strong>
    <p>
      <span ng-bind="task.content"></span>
    </p>
  </div>

  <div class="item tabs tabs-secondary tabs-icon-left">
    <span class="item item-checkbox">
      <label class="checkbox">
        <input type="checkbox" ng-model="task.completed" ng-click="completeTask($index)">
      </label>
    </span>
    <a class="tab-item assertive" ng-click="removeTask($index)">
      <i class="icon ion-android-close"></i>
    </a>
  </div>
</div>
  • With that we have a list of tasks presented with cards in our view.
  • Now to create a new task, we will use the modal which we already configured in our controller.
  • We are tracking the array with a unique $index as it has none specified explicitly in the data source.
  • Instead of adding this as an inline template, which can be messy, let's create a templates folder inside our www/ folder
  • Then, inside our www/templates folder, let's add a new file called new-task-modal.html
<ion-modal-view>
  <ion-header-bar class="bar-dark">
    <h1 class="title">Create a new Task</h1>
    <button class="button button-icon" ng-click="closeTaskModal()">
      <i class="icon ion-android-close"></i>
    </button>
  </ion-header-bar>
  <ion-content>
    <form ng-submit="createTask()">
      <div class="list list-inset">
        <label class="item item-input">
          <input ng-model="task.title" type="text" placeholder="Task title">
        </label>
        <label class="item item-input">
          <textarea ng-model="task.content" rows="5" placeholder="Task content"></textarea>
        </label>
        <ul class="list">
          <li class="item item-toggle">
            Completed?
            <label class="toggle toggle-balanced">
              <input type="checkbox" ng-model="task.completed">
                <div class="track">
                  <div class="handle"></div>
                </div>
            </label>
          </li>
        </ul>
        <button type="submit" class="button button-block button-positive">Create Task</button>
      </div>
    </form>
  </ion-content>
</ion-modal-view>

Now, inside our app.js, lets edit the location of our modal. Change it from new-task-modal.html to templates/new-task-modal.html We also need to add a way to view and close our modal. Inside our controller, let's add two more methods

$scope.openTaskModal = function () {
  $scope.newTaskModal.show();
}

$scope.closeTaskModal = function () {
  $scope.newTaskModal.hide();
}

Finally on the view, add a button to the ion-header-bar directive which will be used to open the modal.

<ion-header-bar class="bar-dark">
  <h1 class="title">Ionic-Todo</h1>
  <!-- New Task button-->
  <button class="button button-icon" ng-click="openTaskModal()">
    <i class="icon ion-compose"></i>
  </button>
</ion-header-bar>

And that is it! That is our sweet simple Todo mobile app.


Deployment

Now that we have our app finished, lets test 2 different ways to get it on our phones so we can use it like an app!

Phonegap Serve

First, we are going to use Phonegap to build and test our application. Let's get that onto our machines

npm install -g phonegap

This will install the command line tool and give us access to use PhoneGap from the CLI. What this will do is to create a server that we can use to run our apps on our phones. Do note though, this is finicky, and doesn't always work

Once we have that installed, instead of running ionic serve, we run

phonegap serve

Once we have ran that, we should see something like this in our terminals (minus the no such file or directory;)

phonegap serve

What we want to look for is the listening on <port number> section. Once we have found that, whip out your phone and go to that endpoint. You should see your server responding to that request

Ionic View

The way above is a hacky way (and does not always work), and is good for quick and dirty testing when you're developing. A more professional way is to use ionic view to view our apps.

First we need to download Ionic view

Next we need to set up our Ionic CLI. It has been a while since I have set mine up, so I apologize if I am forgetting something, but let's walk through this together. Let's all start with

ionic upload and see what happens

  • Once we have our Ionic accounts set up, anytime we want to preview we would run our typical git commands, then simply type ionic upload.
  • From there, we then type ionic share <email address> which will send an email address with a link to view.
  • Once we click on that link, we will go to a website where we will be told everything was successful
  • Exit out of that website, go back to your Ionic View App, and see that you should now have a new app on the homescreen
  • Click on the app, and it should load up natively, just like a normal app!
  • From now on, you will want to clear all data each time you run ionic upload by clicking the gear icon or the app itself

Production Deployment

To make your application available to the world as if it were a 100% native app, you can deploy it on:

  • Google Play Store (Android)
  • Apple's App Store (iOS)

Both platforms require you to join their developer platform for a fee:

  • Google Play Store - One time $25 fee
  • Apple's App Store - Annual fee of $99

Deployment is non-trivial and requires answering a bunch of questions and generating extra resources such as screen shots & icons.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment