In order to start working with Ionic, you first have to install Node. Go ahead and download the installer for your platform if you don’t already have it. If you’re an Ubuntu user, you can install Node using NVM (Node Version Manager). To install NVM, execute the following commands in order:
1 2 3 4 5
The first command, installs the build tools and SSL development libraries. The second downloads the NVM installer, and the third sources the
~/.profile file so that your current command-line session knows about the changes. This basically allows you to use the NVM command without having to logout.
Next, you can now list the available Node versions:
This will list out a whole bunch of Node versions that are available. But usually you would want to install the current version, which is the last item on the list. At the time of writing of this article, the current version is
v0.12.7. So you can go ahead and install that using the
nvm install command:
Now when you check the Node version installed on your machine, you would see
Next you need to set this version as the default, otherwise you’ll have to execute
nvm use v0.12.7 every time you need to use Node.
Cordova and Ionic
Now we’re ready to install Cordova and Ionic:
Once that’s done installing, you can create a new project using the
ionic start command. There are currently 3 available starter templates you can use: blank, tabs, and sidemenu. In this tutorial we’re going to use the tabs.
Ionic Directory Structure
The command above will create a
demoApp directory which contains the following:
1 2 3 4 5 6 7 8 9
hooks directory is where you will put the scripts for customizing Cordova commands. I’ve never had the need to use this feature so I can’t share anything about it. But if you’re just getting started, you wouldn’t normally need to touch this directory.
platforms directory is where the different platforms in which your app will be compiled to is stored. Note that its not there by default, you have to install a platform first.
plugins directory is where Cordova plugins gets installed.
scss directory is where the main Ionic sass file (ionic.app.scss) is stored. It contains the primary variables for customizing the colors used in your app.
www directory as they’re pretty self-explanatory.
bower.json file contains the front-end dependencies of your app. By default it depends on Ionic. All bower dependencies are installed on the
www/lib directory by default. You can install new one’s by using the
bower install command and then link them on the
index.html file in the
www directory. When you install new libraries using bower, use the
--saveDev option so that it will save the package name on the
bower.json file. The
--save option is used to specify that the library you’re installing is a front-end asset. For example, jQuery or Bootstrap. While the
--saveDev option is used for development only. Things like jshint or jasmine.
config.xml file is where you can change the name, description and author of your app. You can also set your preference for device orientation (either portrait or landscape), features and URL’s which your app is allowed to access.
gulpfile.js file is the Gulp config file used by Ionic. Normally you wouldn’t need to touch this. What you need to understand is that this is used by Ionic to execute tasks such as compiling sass files to CSS or watching a specific directory for changes.
ionic.project file is where you can update the name and app_id of your app. You won’t really need to touch this.
package.json file. This contains the dependencies of the Ionic framework. You won’t really need to touch this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
With Cordova there’s only a select few platforms that it supports. So it’s not completely write once, compile to all kind of thing. There are different sets of problems to solve for each platform in which you plan to release your app. The common platforms that you may want to install are android, ios and browser. For a list of all the platforms supported by Cordova, you can check out the Cordova Platform Guides. Each platform has a different dependency. Usually it’s the SDK or the recommended developer tool for that platform. For Android, it’s the Android SDK, for iOS it’s Xcode, for Windows it’s Visual Studio. I’m only going to walk you through the Android platform in this tutorial.
You can download the Android SDK installer from this page. Under the SDK Tools Only section, download the package for your platform. I’m on Ubuntu so I will download the one for Linux. Once the download is done, extract the files using the
tar command or you can also right click on the file and select the archive manager of your choice.
After extraction, it would yield an
android-sdk-linux folder which contains the following:
1 2 3 4
From that directory, navigate to the
tools directory and execute the
Back to where we left. Let’s now install the tools we need to get Cordova do its job. Check the following items on the Android SDK Manager and click on Install. This might take a while depending on your download speed.
Tools – Android SDK Tools
Android 5.1.1 (API 22) – SDK Platform
Android 5.0.1 (API 21) – SDK Platform – Google APIs
Android 4.4W.2 (API 20) – SDK Platform
Android 4.4.2 (API 19) – SDK Platform – Google APIs (ARM System Image)
Extras – Android Support Repository – Android Support Library – Google Repository
Once that’s done installing, add the path in which the Android SDK is installed to your environment. In Ubuntu and OSX, you can add the following on your
1 2 3
In Windows, there’s something called the Environment Variables. I’ve written about it in my old blog: How to set environment variables.
Once that’s done, you can now install the Android platform, you can use the
ionic platform add command followed by the name of the platform you want to install.
You can use sass with ionic by executing the following command while inside your project directory:
What this does is install the packages and tasks needed to compile sass. Then remove the following from your
It also adds the link to the
ionic.app.css file which is basically just the compiled version of the
ionic.app.scss file found in the
Finally, it adds the following in your
ionic.project file. This tells ionic to start the sass and watch command when gulp starts. It also specifies the watch patterns, so that every time you make a change to a file that matches the pattern, the sass command gets executed and compiles the sass files to css.
1 2 3 4 5 6 7 8
If you want to change the default colors used by Ionic, this is where you can do that. Be sure to uncomment the variables just like what we have below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
Now anytime you make a change to the file while running
ionic serve, it will compile it to the
ionic.app.css found at the
Developing an App
You can start developing your app by executing
ionic serve from the root directory of your project. This will launch a new browser tab containing the app. If you’re using Chrome, you can click on the phone icon on the left of the elements tab when you open the developer tools. This would show your app inside a smaller screen depending on the device that you specify. You can change the device by clicking on the drawer icon which looks like this:
>__. And then click on the emulation tab then select the device from the model dropdown. You might need to refresh the page after doing this so that it will render correctly.
Now open the
index.html file in the root directory of your project. This is where every thing is hooked up. If you have ever developed a single-page app before, this would be familiar to you. Basically how a single-page app works is that every script that you need is linked in the
index.html file. You might be thinking this is a bad practice since it will take too long for the page to load. Well it’s not since the front-end assets are included in the app locally. It wouldn’t need to download it over the internet so it’s fast even if we have a lot of files linked in there.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
Ok let’s break this file down. First we set the charset to utf-8 and viewport so that the initial and maximum scale is 1, we also set the
user-scalable option to
no. This basically means the user wouldn’t be able to resize or zoom the app.
Next we have the title. This means nothing since we’re on an app not a website. So users wouldn’t be able to see this. You can leave it as blank.
And we also have the main ionic css file.
We also need to link the
cordova.js file so we can use Cordova within our app. This would allow us to use Cordova plugins as well via
js/controllers.js file, in the default controller created by Ionic, all the controllers are added in a single file. This is fine for really small apps but for medium to large size apps it’s recommended to have a single controller for each entity in your app. For example, you might have a user controller where you put all the code that has something to do with the user. Things like updating user settings. The controller is where you usually put code that responds to a specific event such as clicking a button or pulling to refresh. Lastly, we have the
js/services.js file. A service is responsible for adding a specific functionality to your app. You would want to create a service for making requests to your server, or storing data in local storage. It’s recommended that you search for existing solutions first before writing your own services. So you won’t waste time re-implementing the same thing.
1 2 3
Then we have the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
In a typical Angular app we set the
ng-app attribute to the name of the module. Ionic has used
starter as the name of the module by default. You can change that on your
app.js file. Here the name of the module is starter.
You can change it to the following if you want. Here the name of the module is changed to
If you did change the name of the module. You also need to change the value of the
As well as your controllers and services:
Going back to the
app.js file. This is the code responsible for setting the name of the module and the services and controllers it depends on. By default it depends on the ionic service, and your custom controllers and services.
You can think of
my_awesome_app.services as a submodule of the
my_awesome_app module. We declared those two modules in the
You might be wondering what’s the need for these sub-modules? Well, their main purpose is to have a different parent module for each controller and service. So every controller would depend on the
my_awesome_app.controllers module and all services would depend on the
my_awesome_app.services module. We do this because simply depending on the main module wouldn’t work:
Next we have the
run function. This is where Ionic executes functions which needs to be executed every time the app is opened. All function calls should be wrapped in the
$ionicPlatform.ready event to make sure all the plugins and other features that we need are loaded. Inside the event, we check if the Cordova keyboard plugin is accessible. If it is then we hide the keyboard accessory bar. Finally we use the lightContent statusbar (light text for dark backgrounds) by calling the
styleLightContent method provided by the
1 2 3 4 5 6 7 8 9 10 11 12 13
Next we set the app configuration by calling the
config method in the Angular module. You can use this to set the routes of your app.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
Breaking it down, we use the
$stateProvider to set different states. A state is equivalent to a route in your app. You can call the
state method to create a new route, this accepts the name of the state as its first argument and the config as its second.
1 2 3 4 5 6
A state can be abstract or not. You usually declare a state as an abstract one if it has a child state. In the above example the tab state is an abstract one. This means you don’t access it directly from your browser. Instead, you access its child states. In this case the child states are
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
An abstract state takes the following options:
- url – the URL that you will use to access the state. For an abstract state, this would be the parent URL that each child state will use.
- abstract – a boolean value that is set to
trueto specify that the state is an abstract one.
- templateUrl – the path to where the template is located locally.
A child state would accept the same options, the only difference is that you have to set the
views option and the add a single property with the name of the view. Then that property would have the
templateUrl property and
controller which is basically the name of the controller that the state uses. The
controller property is optional, you can set this on the template if you want. But you have to note that you can’t specify the controller name on both the template and the
app.js file. Otherwise methods that run every time the controller is executed is called twice. Here is a sample child state. As you can see the
url is set to
/chats but you would need to specify the URL of the abstract state first. So accessing it in the brower would be
1 2 3 4 5 6 7
Next we specify the views with the
view property. As I’ve said earlier, this accepts the name of the view as its property. This is tied with the name of the view in the
ion-tabs directive. You can find it in the
templates/tabs.html file. The view
name property in the
ion-nav-view directive should be the same as the name of view in your state declaration.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
Now open up the
controllers.js file. On the first line we’re declaring a new module called
my_awesome_app.controllers. If you remember from earlier, this is one of the modules that we specified as a dependency for the main module in the
Then we create a new controller by using the
controller method. This accepts the name of the controller as its first argument and the function to execute when the controller is accessed as its second. For the
DashCtrl, we have an empty function body as we do not need to execute anything.
ChatCtrl, we get a list of chat messages using the
Chats services. We’ll go through that in a moment, but for now understand that to use a service you need to declare it as a parameter in the function body of the controller. This way you can access it from inside the function and call the different methods that are accessible from that service. Also notice that we have also declared a
$scope variable as a parameter. This allows us to pass in data to the current scope. We do this so we can access the data in the view. Back to the
Chats service, we are calling the
all method in the
Chats service. This returns an array of messages. We then assign whatever it returns to the
chats property in the
$scope. Note that you can name it anything you want. Next we’re also assigning a
remove method to the
$scope. What this does is remove a specific chat message.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Here’s the view utilizing the
ChatsCtrl. It’s in the
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
ChatDetailCtrl is the controller responsible for showing the details of a specific chat message. Here we’re using a new parameter in the function body called
$stateParams. This allows us to get the value of a specific route parameter. Route parameters are passed in the URL of the app. If you go back to the
app.js file, you can see from the
tab.chat-detail state’s URL is
:chatId here is the route parameter. Every route parameter in Angular always starts in a colon followed by the name. So in the
ChatDetailCtrl we are merely getting the value passed in this route parameter and then using it as an argument for the
get method in the
Chats service. This method basically fetches a specific chat message from the array of chats. We then just assign the value to the
chat variable in the
1 2 3
You can see this being used in the
1 2 3 4 5 6 7 8
Finally we have the
AccountCtrl. Nothing fancy here. All we’re doing is passing in an object to the scope.
1 2 3 4 5
We can see this being used from the view in
1 2 3 4 5 6 7 8 9
From the above HTML, the
enableFriends property is used as the model for the
ion-toggle directive which basically just outputs a switch UI. In this case the switch should be turned on since the value of the
enableFriends property is
Now we take a look at the service file at
js/services.js. Same with the controllers, we declare a new module called
my_awesome_app.services. From there we call the
factory method in order to create a service. We call this service
Chats. Inside the function body, we have an array of objects containing the details for each chat message. After that, we expose the methods that we want the controllers that will use this service to use by returning them. Here we have 3 methods, the
all method which just returns all the chat messages. The
remove method which removes a specific chat message from the array of chat messages. And last is the
get method, which returns a specific chat message based on the id.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
You can install plugins by using the
ionic plugin add command. Here’s an example of how we might add the camera plugin:
If you decide later on that you no longer need a plugin, you can use the
ionic plugin rm command:
Every plugin already has the necessary instructions which will setup everything that is needed in order for it to work when installed. Things like putting the necessary permissions in the
AndroidManifest.xml file so that you can use specific features of the device.
I won’t dive in much into plugins, what’s important is that you know they are available and you can use Google to look for them. There’s the Cordova Plugin Repository and Github if you want to look for a plugin that can solve your specific problem.
Changing the App Icon and Splash Screens
To change the icon of the app, simply put an
icon.ai on the
resources directory in the root of your app. For the splash it’s
splash.ai. The recommended icon size is 500x500 and the splash image is 1200x1200. Once you’ve added the files, execute
ionic resources from the terminal to generate your icons and splash screens.
Compiling to Android
You can create an apk file using the
ionic build android command. This will create the
android-debug.apk file under the
platforms/android/build/outputs/apk directory. Note that this is the debug version of the app. You can use this for testing on your mobile device. But you cannot submit it to the Google Play Store. To do that you’ll have to build a release version for your apk by adding the
--release option when using the
cordova build. Note that we’re using
cordova instead of
ionic. Ionic simply wraps the Cordova commands so you can use them interchangeably.
Next, generate a keystore for the app by using
keytool. Breaking down the command below, we’re setting the following options:
- genkey – not actually an option, but a command to generate the key.
- keystore – the file name you want to give to the keystore
- alias – the alias of the key.
- keyalg – the algorithm to be used to generate the key.
- keysize – the size of the key in bytes.
- validity – the number of days in which this keystore will be valid.
Executing the command above will ask you for the keystore password and some questions. Just provide an answer to each question since the information that you supply will be used to generate the keystore. Here’s how it looks like in my machine:
If you cannot use keytool, then maybe you don’t have Java installed yet. You can install it by executing the following commands in order.
1 2 3 4 5 6 7
Now we’re ready to sign the apk file with the keystore that we generated. To do that, first copy the
demoApp.keystore to the
platforms/android/build/outputs/apk directory, open a terminal on that directory then execute the following command:
This will ask you for the password that you entered earlier when you created the keystore.
Finally, to generate the apk that you can submit in the Google Play Store, use
zipalign. This accepts the name of the unsigned apk file and the name of the signed apk which it will generate.
If you need the key you can execute the following:
That’s it! In this tutorial you’ve learned the basics of working with the Ionic framework. We have only scratched the surface in this tutorial, be sure to check out the resources below to learn more.