Ionic

The Happy path to Hybrid Apps

Josh Bavari

Ionic Tools Developer

Hybrid Apps!

HTML5 that acts like native

Web wrapped in native layer

Direct access to native APIs

Familiar web dev environment

A single code base (web platform!)

“It's not 2007 anymore”
Year Device Processor RAM
2007 iPhone 620 MHz 128 MB
2010 iPhone 4 1 GHz 512 MB
2015 iPhone 6 1.4 GHz dual-core 1 GB

Web-standards

Have improved!

caniuse.com is lookin' pretty good nowadays

Android is now Chromium-based

iOS users keep their devices up-to-date

https://mixpanel.com/trends/#report/ios_8/from_date:-141,report_unit:day,to_date:0

https://mixpanel.com/trends/#report/android_os_adoption

Problems you'll probably face

  • Firstly - getting started
  • Handling native look & feel - iOS / Android
  • A common UI Kit
  • Navigation throughout the application
  • Performance
  • Accessing Native SDKs

Native SDKs...

Are Great!

Common UI, APIs, views, navigation, stack history, transitions, interactions, gestures, etc.

How does one make this process easier?

Web Technologies You Already

Know & Love

(You'll feel right at home)

Standing on the Shoulders

of Angular

Extends the HTML vocabulary

Proven for large-scale app development

UI Components using Directives & Services

Sass!

CSS generated from the Sass preprocessor

Quickly give your app its own look and feel

CSS designed to be easily overridden

Variables based with default settings

How it all comes together

  • Your App
  • Ionic
  • Angular
  • WebView (Cordova)
  • Native App

Collection Repeat

  • Replacement for Angular's ng-repeat
  • Inspired by iOS’s UICollectionView
  • Scroll through thousands of items
  • Only renders the viewable items
  • Smooth scrolling!

{{ c.name }}

{{ c.email }}

Navigation

  • Uses AngularUI Router
  • Shows back button when possible
  • Transitions follow direction of nav
  • Updates the app's URL
  • Multi-history stack



  
    
  

  
    
  

  
    
  

Cached Views

  • View elements left in the DOM
  • $scope disconnected when cached
  • State maintained
  • Scroll positions maintained
  • Life Cycle events
  • Highly configurable

Swipe To Go Back

  • Swipe back to previous view
  • Interactive transition
  • Benefit of cached views
  • Still updates the app's URL
  • WebView (Cordova) only

Other Components

  • Side Menus
  • Actionsheet
  • Modal
  • Pull To Refresh
  • Slidebox
  • Infinite Scroll
  • Swipeable List Options
  • Popup
  • Popover
  • Loading Overlay
  • Inputs
  • Buttons
  • etc.

Ionicons

700+ MIT licensed font-icons included

ionicons.com

Spinners

  • Animated SVGs
  • More than just rotating icons
  • Defaults to platform's spinner
  • Style with CSS





Top notch documentation

Let's look at it

Let's peek at boilerplate code

Basic App With States


angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])

.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if(window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if(window.StatusBar) {
      // org.apache.cordova.statusbar required
      StatusBar.styleDefault();
    }
  });
})

.config(function($stateProvider, $urlRouterProvider) {

  // Ionic uses AngularUI Router which uses the concept of states
  // Learn more here: https://github.com/angular-ui/ui-router
  // Set up the various states which the app can be in.
  // Each state's controller can be found in controllers.js
  $stateProvider

    // setup an abstract state for the tabs directive
    .state('tab', {
      url: "/tab",
      abstract: true,
      templateUrl: "templates/tabs.html"
    })

    // Each tab has its own nav history stack:

    .state('tab.dash', {
      url: '/dash',
      views: {
        'tab-dash': {
          templateUrl: 'templates/tab-dash.html',
          controller: 'DashCtrl'
        }
      }
    })

    .state('tab.friends', {
      url: '/friends',
      views: {
        'tab-friends': {
          templateUrl: 'templates/tab-friends.html',
          controller: 'FriendsCtrl'
        }
      }
    })
    .state('tab.friend-detail', {
      url: '/friend/:friendId',
      views: {
        'tab-friends': {
          templateUrl: 'templates/friend-detail.html',
          controller: 'FriendDetailCtrl'
        }
      }
    })

    .state('tab.account', {
      url: '/account',
      views: {
        'tab-account': {
          templateUrl: 'templates/tab-account.html',
          controller: 'AccountCtrl'
        }
      }
    });

  // if none of the above states are matched, use this as the fallback
  $urlRouterProvider.otherwise('/tab/dash');

});
          

An Angular Service


angular.module('starter.services', [])

/**
 * A simple example service that returns some data.
 */
.factory('Friends', function() {
  // Might use a resource here that returns a JSON array

  // Some fake testing data
  var friends = [
    { id: 0, name: 'Scruff McGruff' },
    { id: 1, name: 'G.I. Joe' },
    { id: 2, name: 'Miss Frizzle' },
    { id: 3, name: 'Ash Ketchum' }
  ];

  return {
    all: function() {
      return friends;
    },
    get: function(friendId) {
      // Simple index lookup
      return friends[friendId];
    }
  }
});
          

Angular Controller


angular.module('starter.controllers', [])

.controller('DashCtrl', function($scope) {
})

.controller('FriendsCtrl', function($scope, Friends, $ionicActionSheet) {
  $scope.friends = Friends.all();
  
  // Triggered on a button click, or some other target
  $scope.show = function() {

    // Show the action sheet
    var hideSheet = $ionicActionSheet.show({
      buttons: [
        { text: 'Share This' },
        { text: 'Move' }
      ],
      destructiveText: 'Delete',
      titleText: 'Modify your album',
      cancelText: 'Cancel',
      cancel: function() {
           // add cancel code..
         },
      buttonClicked: function(index) {
        return true;
      }
    });
})

.controller('FriendDetailCtrl', function($scope, $stateParams, Friends) {
  $scope.friend = Friends.get($stateParams.friendId);
})

.controller('AccountCtrl', function($scope) {
});

          
...but there's more to Ionic

npm install -g ionic cordova

Boilerplate app structure ready for customization

LiveReload both local and native builds

Build and run native apps

Not a fan of command line tools?

We've got an app for that..

Introducing Ionic Labs

Start a server

Preview iOS / Android quickly

Run your native app, and more..

Demo Time!

May the demo gods be with us

Modern

Chromium!

Chromium for Android WebViews

Upgrade Android 4.0+ and above

Same hardware, modern software

Amazing performance improvements

Ionic's Adoption

  • 16,000+ Github Stars
  • Top 50 most starred Github repos
  • Consistently Top 10 trending JS Github repos
  • 400,000+ Ionic apps have been started from our CLI
  • Released Alpha: November 2013
  • Released Beta: March 2014
  • Releasing 1.0: May 2015

You're probably wondering..

Angular 2?

Yes, we are working with the Angular team.

Angular CLI - Ionic will be supported!

What's Next!

  • Ionic 2 with Angular 2!
  • Component Modularity
  • Ionic app scaffolding
  • Customized Animations
  • Webworkers and Multi-threading
  • Ionic Labs - GUI for app tasks

</html>

@jbavari

http://jbavari.github.io/ionic-happy-path