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!

The Curse of Knowledge

Try this. Pick a tune in your head, something most people would easily recognise. Find someone and tap the tune out. Tap, not hum. See if they get it.

How annoyed or frustrated do you get if they can’t get something that seems so obvious to you? I am somewhat ashamed that I wasn’t able to recognise “Happy Birthday” when Marty tried it on me, though it did prove a point.

When you know something, and you know it well, it’s hard to imagine how someone else could possible not know about it. Until we develop ET-like powers of psychic connection, most experiential or knowledge exchange is carried out under context deficient conditions and restricted by language. Remember the mythical swing?

This is hardly an insight. What is perhaps less stated is its censorship effects. One of the common reasons I abandon an idea or poject is because it seems so obvious that I feel embarassed to mention it, or even write a whole article about it. Especially since someone could easily reach the same level of understanding if they spent enough time googling for it.

I think this self-censorship robs us twofold. It robs us of an opportunity to synthesise and refine our thoughts in writing, but also robs the rest of the world of your insight that may not be all that obvious to them.

One of the most visited pages on this blog is about an Android related build system problem. This is despite there existing a stackoverflow post about it that’s shorter and more concise. There is value in your unique synthesis and contextual insight.

So stop crossing out those ideas for projects and articles. It could even be about something as mundane as fried rice. πŸ™‚

Fried Rice, Very Nice

Yesterday I cooked fried rice. It was probably the best fried rice I’ve cooked ever, and I’ve cooked a few.

I’ve never had any real education where cooking is concerned; when I was growing up in Singapore, my family had a domestic servant (read: maid) who did all the cooking, cleaning and washing. All the way up until I left Singapore for Uni in Sydney, I never had to cook.

Consequently, any cooking I did was very much the way I was brought up; by the book. Even today, my approach to cooking usually goes like this:

  • Find a recipe online
  • Measure out each of the ingredients in the recipe
  • Follow the recipe to the letter

As you can imagine, this didn’t always result in a dish that resembled the recipe, or tasted the way I had imagined it to be. Often things like “until fragrant”, “until cooked through”, or something which didn’t have a precise time or visual measurement associated with it didn’t work too well.

Yesterday was different. I still looked up a receipe, but not only did I have totally different ingredients for the recipe, I didn’t actually measure them out. Instead I just mixed stuff in and tasted as I went along.

Some years back, there was a popular sitcom on Singaporean TV called Under one roof, about a Singaporean family. In one of the episodes, the mother is trying to teach her daughter how to cook. She used phrases like “just put some oil”, or “add a bit of salt”, much to the chagrin of her scientific-method oriented daughter. The daughter then started measuring how much oil acutally corresponded to “some oil” and how much salt was “a bit of salt”, and found incredible consistency between trials attempted by her mother.

I think well-practised cooks get the same measurements and dosages consistently. Good cooks taste as they go and know how to adapt to different states of a dish. Better cooks have a wider range of ingredients to play with when adapting a dish, and the best cooks are consistent through practice, have a wide range of ingredients at their disposal, and efficiently execute quickly. Consqeuently, they are able to handle much more complicated dishes in the comparable amount of time as the average cook.

You can probably see where this is going. I think well-practised software developers produce consistent, familiar code. Good developers iterate quickly and adapt to customer feedback. Better developers have various techniques to use when adapting to change, and the best developers can do this in a much shorter period of time. Consequently, they are able to handle larger, more complicated projects than the average developer.

I got a glimpse of being a good cook yesterday, but my only tools are salt, pepper, soya sauce and oyster sauce. I certainly cannot produce consistently and am some ways away from amassing a reasonable body of knowledge to adapt to different states of a dish. Soya sauce, salt, pepper, oyster sauce, fish sauce and seasame oil are still the best cooking friends I have. But I’m getting there.

Still a long way to go, where software and cooking are concerned, but here’s a picture for posterity.

It also helps if you add a liberal dose of oil πŸ™‚

From Dublin with love

Despite my best attempts, this blog post is stilll almost 2 months late. For all the talk about consistency, I was still unable to put pen to paper and get things done.

This happened even though I had numerous ideas about what to write, going as far as to write outlines and code samples but never actually putting it together.

I don’t think it was the difficulty of finding topics, I think it was the dread and expectation of the arduousness and pain I would need to go through to actually craft a piece. That probably wouldn’t end up being that hot anyway.

There is a mantra that’s grown more common among software folks in the last few years. Ship fast, Ship often. It works because you get used to the pain, rather than forgetting it. It works because you find ways to deal with what’s constantly in your face, rather than hours slogging through it each time.

It’s not a new invention. Successful blog writers have long advocated the virtues of releasing consistently with a schedule. And I’ve always thought I’d be good at following a schedule. When I was in school, my annual report card usually had some remark about “high self discipline”. As it turns ot, following what someone tells you to do is not the same as following goals you set for yourself.

Being obedient is not the same as being as being self motivated.

A long time ago, in a galaxy far far away, I was a reasonable runner. I even took part in a 4 x 100 track relays for my class. It was a time when I would run around 6km every Sunday. I would meet Mr. Wee, a friend of mine, at the same place every Sunday morning and we would jog down for breakfast.

We didn’t always make it all the way there (sometimes we even skipped the run altogether!), but we would show up.

Years later, as I’m writing this here in Dublin, all that seems rather far away. I’m not sure when we’ll make it back to Sydney for any extended period of time, and I’m even worse at keeping in touch with the folks from Singapore.

Who knows what the future holds, or where this post actually leading to. I do know I had to get it out, even though no one was really pushing me to. And it cannot end without a solution, because what seems like the hopelessness of a hopeless problem is a poor excuse for not trying to solve it.

So I’ll ship fast and ship often, with a blog every Saturday. Next one will be on 15/11, so stay tuned!

“bad constant pool tag 18” with sbt and JDK 8

Scala < 2.10.4 does not play well with JDK 8, thanks to invokedynamic being used in some JDK classes (see https://groups.google.com/forum/#!topic/scala-user/Nzc2zUTyays).

If you can use JDK 7, it is probably the easiest workaround. If you have to use JDK 8, upgrading to sbt >= 0.13.5 is also an option, since those sbt versions use Scala 2.10.4 (See http://www.scala-sbt.org/0.13/docs/Changes.html)

Sadly, this can lead to other issues, such as libraries being only available for Scala 2.9.x and not 2.10.x. YMMV. Happy building ;P

https in layman terms

This will be a quick primer for public key cryptography in layman terms. I’d like to use the content for a Toastmasters’ speech in the not too distant future, hopefully leading to a Bitcoin presentation.

We often take for granted how easy it is to send messages securely over the internet. From filing taxes to transferring money, “how conveniently can it be done”, as opposed to “how securely can it be done” is the usual question. What does it really mean to be secure over the internet though? What does the green lock you see when you run your browser really mean?

Let’s try and walk through the steps involved in making a bank transfer, and see what could go wrong.

As is the tradition in IT security, we will use the characters Alice and Bob. Alice wants to transfer $100 to Bob. At her terminal, she wants to send a message the equivalent of “transfer $100 from my account to Bob”.

This message has to travel across numerous connections till it finally gets to the bank, where it is read and processed.

How can we prevent anyone else along the way from reading Alice’s message? Apart from buying over all the links to our bank on the internet, one option would be to scramble the message and foil any would-be eavesdroppers. This is known as encryption, and would work, except that Alice’s bank would need to know how to unscramble the message and actually process it.

Encryption is not a new problem, many methods/algorithms exist, but they all rely on a specific “key” that is known beforehand. How would it know beforehand how to get this key? It would also need to make a different one for each account holder, otherwise any customer of the bank could read any other customer’s data.

You can’t really send the key over the internet since that could be intercepted and read. You could go to your bank and negotiate some kind of secret, common key beforehand. That would work, but it wouldn’t be very feasible for all parties you’d like to conduct a transaction with, like say Amazon.

The solution that was eventually adopted used a neat bit of math. Rather than using the same, single “key” that both alice and her bank could decrypt/encrypt with, a type of encryption method exists where each party has two keys. These keys are often called private and public keys, for reasons that will become obvious soon. A message encrypted using the bank’s public key can only be decrypted using bank’s private key, and vice versa. The key thing here is that knowledge of the public key does not allow you to decrypt the message.

In practice, any website that operates over https as opposed to http has generated a pair of keys. Your web browser automatically does the required encryption using the website’s public key. When you visit a https website, the website presents its public key to you and you then use it for encrypted communications.

The more eagle-eyed or technically inclined audience might spot a problem here. Suppose Eve controls one of the computers along the chain. When the initial public key is being sent to Alice, she instead replaces the bank’s public key with one of her own, so that Alice now encrypts her data using Eve’s public key. Eve can now intercept the messages and relay them to the bank, possibly modified to say transfer money to her account.

This can be prevented if we knew beforehand what the bank’s public key actually was, without actually needing the bank to present itself. Some kind of centralised key registry. However, this key registry would need to be dynamic since new websites are registered all the time, and you would need to “know” the public key of this centralised key registry in order to start the whole process in a secure fashion.

In practice, what happens is not so different. A secure website doesnt just present its public key, the public key forms part of a certificate. Just like say a birth certificate, it is meant to certify the identity of the website, so it contains the entity name, organisation etc. The interesting technical part of all this is the certificate is usually certified by a certification authority (remember key repository?). This certification authority in turn is usually certified by yet another certification authority, and so on until we reach a root certification authority. Your browser, when installed, contains files that can be used to verify only these root certification authorities. This is known as a certificate chain, one end of the chain is the website you are visiting, and on the other end a root certification authority that your browser knows about.

So at the end of the day, here’s what happens when you visit a secure website, in somewhat simplified terms:

  • The website presents you with its public key as part of the website’s certificate. The certificate has been issued by a certification authority.
  • Your browser verifies that this certification authority has been certified, directly or indirectly by a root certification authority it knows about.
  • When satisfied that the public key it has received really belongs to the website you are visiting, it then starts transferring data encrypted with this public key
  • The receiving website then uses its private key to decrypt the data it receives, and to encrypt its response.

All this takes place when you visit a website such as https://bank.barclays.co.uk . You can even inspect the certificate for yourself.

In practice, the process is actually a little more complicated than I’ve outlined. Certificates can have different standards and levels depending on how rigorously a certification authority has verified the identity of a website; encryption and descryption using public and private keys can be computationally expensive and a shared key is often generated and used for encryption once a secure session has been set up using the private and public keys. However, he ideas of identify verification by a 3rd party and the use of public and private keys for encryption/decryption is largely as described.

I hope I’ve given you a quick overview of what interacting with a secure website actually entails. In my next talk, I’ll try and extend some of these ideas a little further and outline how they relate to a decentralised currency like Bitcoin. To be continued πŸ˜›

Should I be happy or annoyed for this hobo?

β€œTack sΓ₯ mycket, tack sΓ₯ mycket, tack… tack sΓ₯ mycket”, the hobo murmured. Cross-legged on the corner of HΓΆtorget Tunnelbana station, he was uttering the equivalent of β€œthank you so much” in an endless loop. Probably aged around 20-ish, he often addressed me on my way to the office with a smirk on his face. He wore nice clothes for a hobo, with jacket and shirt that even appeared to be ironed. No holes noticed. He was never unshaven, and his brightly lit eyes, sneaked excitement of the things he probably planned to use his begging money for.

I vouched to never give him money. Actually I will go one step further, I vouch to never give money to hobos in Stockholm. Ever. If one of your friends who have been here told you that all Stockholm’s hobos don’t look like hobos, you better believe it, because they are right. Hobos here wear leather shoes, so stylish that makes Potato Y easily qualify as a Swedish hobo, accompanied with his laptop and a cardboard on his chest that says, β€œWill program for food”. (He may pick up more money than them too).

Back to the hobo I see every morning, he looks cleaner and sleeker every day, and yet he’s still begging and showing no intention to move on. Should I be happy that his life seems to be going so well, or should I be annoyed? Why can’t he find something else to do that is more useful than sitting on his arse all day?

Maybe I should go too

I stood in front of the train station’s entrance, observing. People passed through me like swarms of flies, some fast, some slow. Two teenagers caught my eye, they were multitasking. Both girls walked slowly past the gates, talking to each other, while looking intently at their phones, as if they were speaking to each other through the microphones. A boy, running for the train, accidentally pushed one of the girls, just hard enough to snatch her out of the semi-virtual conversation. She got angry, but the boy had already disappeared. An old lady bumbled along, pulled in different directions by three big dogs she held on to. A family of five tried to go through the exit rather than the entrance, although the pathway was clearly labeled for commuters to get out. The exiting swarms did not care about what the family wanted to do, so the family gave up and re-entered through the correct entrance.

I thought it was like life, no matter in what manner we went through the gate, or how many times we tried to enter, everyone would eventually catch the train. Only those who stood still would miss the train, like me, because I was still observing. Maybe I should go too.

 

576551284