Hands on with Ionic, part 1

I’ve been playing with a nifty framework called Ionic recently. Ionic is a framework for developing hybrid apps that is tied to AngularJS. Since I’d previously worked with AngularJS it seemed right up my alley.

I’m going to walk through building an app using the framework. In particular, I’m going to build an application called BGG Scanner that will look up Board Games on Board Game Geek based on a barcode scan. Through this, we’ll cover getting started, using libraries, native device features and testing. More on this later, but first, what is it I’m actually talking about.

It’s going to take a few posts, so this will be a brief introduction and making sure you’ve got things set up before going any further. In this post we’re going to:

  • Introduce Ionic and Angular
  • Make sure you can run the emulator
  • Introduce our board game problem

.. so we’re all set up for part 2!

What is Ionic?

Ionic is like Bootstrap for hybrid apps – it has CSS styles and elements that mimic native mobile platform elements, as well as javascript components specifically for use in Angular applications. Most of its javascript components deal with UI elements, such as modals, tabs and loading screens, but it also has utilities such as gesture detection and history management.

Here’s a kitchen sink example:

See the Pen winLd by Steven Iseki (@StevenIseki) on CodePen.

Ionic uses Cordova for native support, giving it access to the plethora of Cordova/Phonegap plugins. The same folks behind Ionic, Drifty, also have a project called ngCordova that exposes a number of popular Cordova plugins as Angular components.

You can find a more detailed introduction over at the Ionic framework website.

What is Angular?

If you build web applications, you’ve probably already heard of AngularJS. AngularJS is a framework for building single-page web applications. It seems heavily inspired by Spring and JSP-style webapps as it makes use of dependency-injection and an MVC-like architecture involving routes, controllers and views.

Here’s a set of route declarations, which include the mapping between views, routes and controllers.

The views are HTML templates (hence templateUrl), and are tied together with controllers by a $scope object. Any properties available on the scope object are available in the view through the use of {{}} interpolations.

Unlike JSPs, the views cannot directly include code blocks <% %> style, but you can write your own equivalent of custom tag libraries.

Controllers in turn do much of the heavy lifting for each view. They get their dependencies injected at run time, dependencies being Angular constructs such as factories, services, constants and so on. The $scope object is injected in this fashion. It’s very spring-ish and provides similar testability benefits.

and altogether now:

See the Pen xbENeR by Min’an (@mtan) on CodePen.

There’s tons more that Angular provides, including crown jewels like two-way binding. I started off with Angular after watching an hour-long video introducing various Angular constructs.

If you prefer a just-let-me-code approach, the Angular project also has a step-by-step tutorial available that covers not only the basics but how to test each step along the way. They’ve recently added a codeschool course that I haven’t tried but looks pretty cool.

Ionic and Angular, sitting in a tree

Ionic provides a number of UI components through Angular constructs. In JSP parlance, it not only includes custom tag libraries, but also components that can be dependency injected.

Note the presence of the status bar and back button, as well as the larger, mobile friendly buttons below:

See the Pen MYjRGX by Min’an (@mtan) on CodePen.

If we compare the Ionic example with the barebones Angular example we had earlier, we see a number of differences.

  • Controllers look almost the same, except when mapping out routes Ionic doesn’t use $routeProvider but uses something else called $stateProvider. It’s because Ionic uses the more UI-router which allows for more flexible routing rules. That said, the syntax is mostly similar.
  • Ionic introduces custom elements like <ion-nav-view> and <ion-content>. These elements provide the default mobile-themed styling as well as additional javascript behaviour. If you are interested in how this is done in Angular, check out its custom directives

Apart from that, it looks pretty similar and you get mobile-themed styling for free.

Actually getting started

Diego Netto has provided a yeoman generator for ionic that does a number of things out of the box. Yeoman is a scaffolding tool for setting up projects and boilerplate code. Different yeoman generators are available for different projects. I’ll go into some of the cool things the ionic generator does as we cover testing, but for now, let’s get started!

Prerequisites

To test locally:

To actually create an app,

If you’re using Android, you’ll also need to set an ANDROID_HOME env var to point to where the SDK is installed

I’ll also assume you have Chrome to help with mobile device previews and Safari if you’re doing iOS.

I’m using

npm -v 1.4.23  
node -v 0.10.31  
ionic -v 1.2.13  
cordova -v 3.6.3-0.2.13  
yo -v 1.3.3  
npm list -g ionic-generator 0.6.1  

Once you’ve got them installed, let’s dive in

Creating an ionic project

mkdir bgg-scanner  
yo ionic:app bgg-scanner  

You’ll end up with a project structure like so:

├── Gruntfile.js            - Configuration of all Grunt tasks
├── package.json            - Dev dependencies and required Cordova plugins
├── bower.json              - Lists front-end dependencies
├── config.xml              - Global Cordova configuration
├── .gitignore              - Best practices for checking in Cordova apps
├── resources/              - Scaffolded placeholder Icons and Splashscreens
│   ├── ios/
│   ├── android/
├── app/
│   ├── index.html          - Main Ionic app entry point
│   ├── lib/                - Libraries managed by Bower
│   ├── scripts/            - Custom AngularJS Scripts
│   ├── styles/             - Stylesheets
│   ├── templates/          - HTML views
├── platforms/              - Targeted operating systems
├── plugins/                - Native plugins
├── hooks/                  - Cordova lifecycle hooks
├── merges/                 - Platform specific overrides
├── coverage/               - Istanbul reports
├── test/                   - Unit tests
│   ├── spec/
├── www/                    - Copied from app/ to be used by Cordova 

Most things you’ll need to touch will be in the app subfolder. For now, let’s check out how our app looks.

grunt serve  

which will open a browser with your spanking new app. You can then use something like Chrome’s developer tools to preview mobile browsers.

Seeing it on an actual device

Let’s see how it looks like on a native platform. You’ll first have to add an appropriate platform to the project:

grunt platform:add:ios  

and then

grunt emulate:ios  

Replacing ios with android if needed.

If you leave off the platform, e.g. grunt emulate, it will emulate all the platforms you have added.

If you have a device, you can run the app directly using

grunt run  

You will need the npm module ios-deploy to to do direct deploys on iOS devices. npm install -g ios-deploy will do the trick.

That said, the ios emulator is pretty snappy and should be sufficient for most cases (and quicker!)

If you want to distribute archives for installation, you will need to build them first. To build an apk for Android

grunt build:android  

and you will find it in platforms/android/ant-build

If you want to build an archive for iOS, it’s a little more complicated. You’ll still have to do

grunt build:ios  

which will create an Xcode project in platforms/ios. You can then open it in Xcode, from which you can create archives or make use of iTunes Connect for distribution.

A really cool feature of Ionic is its live reload capability. If you add --livereload to your emulate command, i.e.

grunt emulate --livereload  

It will run emulators with the app for all project platforms AND reload them when a change is detected. Now that we’ve got that out of the way, let’s get started!

Our problem

We don't often shop for board games...but when we do we buy the whole shop

Ok, not the whole shop, but it’s a tiresome affair. We usually walk into game stores with hundreds of games, and it’s not obvious which ones will be good. We want a way to pick up a game and tell if it’s worth getting there and then.

The usual solution to this is to search on Board Game Geek. Smartphones have come a long way but it’s still no walk in the park to enter in a dozen or so titles and pore through a mobile-unfriendly site to get the information you want.

A solution

Let’s scan barcodes instead. We can obtain information from BGG and Amazon – BGG to figure out how good the game is, and Amazon to figure out if the price is reasonable.

BGG Scanner mockup - scan, lookup and display info

After I showed something working to Marty things got more complicated but we’ll get to that 😉

In the next part we’ll sketch out how this might work and start making some actual mockups using Ionic.

Parents and the Karate Kid

Initial thoughts after browsing through the React docs –

AngularJS is like your parents, complicated relationship but can get the heavy lifting stuff done for you quickly. It can also have some performance issues because it’s trying to look out for things you don’t care for.

React is like a young karate kid. Capable of great things and performance but needs lots of training. Expensive upfront because you need to think through your models more.

To be fair I’ve used AngularJS alot more, but React is looking pretty interesting!