June 19, 2015
Building Native Apps - Part 4
Building native mobile apps with Ionic Framework and Drupal back-end: request data from Drupal
Define app constants
Now we have a REST server from which we will get all required data for our application. First of all let’s define an Angular constant and store some configuration variables in it - for example, where we’ll we set the base url for services requests. In the app.js file, add a new constant method with that value.
Ionic Framework comes with a couple of useful directives that can help in app building. I decided to make one small user experience improvement: when categories list our article details page as loading, we should show a loading overlay to indicate progress. To do this, we will use the $ionicLoading service. To change its default options you must add another constant - $ionicLoadingConfig - to the app.js file.
Previously, we had defined factories for categories and articles in the services.js file, but the endpoints were empty. Now we can set them. First of all, we have to transfer newly created config objects to the factories and prefix url property value in $http options object with config.serviceBaseUrl. We should also pass the page parameter to Categories get and Articles all methods to handle pagination. And finally we set endpoint variables. Here is the final services.js:
Now we should create templates for each tab using Ionic directives. Let’s look closer at the index.html file. Here we have a main Angular directive ng-app, which defines our app on a global scope; inside it we can see ion-nav-bar, the global dynamic navigation bar. Next to it there is the ion-nav-view directive; this helps to handle application routing according to the UI Router config in app.js. All template content should render inside this directive.
The first screen of our app is a tab with an all articles list, using the tab-articles template. Here we use ion-view to define the tab controller scope and set the title of this page with the view-title directive. Inside this view we set the container for content with ion-content. Inside it we set ion-list with an ion-item child. Also, we set the ng-repeat directive in ion-item. Angular should walk though all articles data and render each article with title and image; for image, we use ng-src directive instead of src attribute. At the bottom of ion-content we add ion-infiniteiscroll - it gives us an opportunity to portionally load more articles.
The template for the single category is very similar to the articles tab; the changes are in the link structure to the article details pages, and the view title, which in this case will be the name of the current category.
On the categories tab we should show the list of categories with the number of articles in each; the list item should be linked to a single category page.
The last template that we need is an article-details.html. Here, we will show the article image, title and body text. We use the ng-bind-html directive to render the body with its html markup, for example: paragraphs, lists, links etc..
Previously we have created empty controllers for all templates, so we will add the code for them now. We should start from more simple controllers: CategoriesCtrl and ArticleDetailCtrl. CategoriesCtrl are attached to the tab-categories template; we will pass the $ionicLoading service to it, to show data loading progress to user. Inside this controller we show a loading overlay calling the show method on $ionicLoading, and load categories list with Categories factory. All of our factories return promises, so after the call it method we then add the method in which we pass 2 functions: first will run on success, second on error. In this tutorial I route all error messages to the browser console.
ArticleDetailCtrl is the same, but here we get an article data by its id, which we get from the state parameter.
CategoryCtrl and ArticlesCtrl are similar so we define a loadMore function in them, that will try to load more articles on scrolling the page down and concatenating them with articles that have been already loaded. Then it will broadcast that the infinite scroll process was completed, and there are no additional results.
You can clone and try all this code from my github repository; to get code for this part, checkout the part4 branch(just run “git checkout -f part4”).
Test, build and compile
Before compiling and testing an app on an emulator or real device you may run it in the browser with command “ionic serve” from you project directory.
If the application worked fine in your browser you can test it in emulators, but first let’s add a platform to our project with command “ionic platform add android”, if you are using a Mac you can also add iOS platform with the command “ionic platform add ios”. Before running the app in emulator you must build it and run “ionic build android” (“ionic build ios” for iOS app). Then you can try the application in emulator by running “ionic emulate android” to emulate it in the native Android emulator that comes with Android SDK, or by running “ionic run android” to use the Genymotion emulator (it is faster and has a lot of device settings), which you can get here.
To emulate iOS you must work on Mac OS and run “ionic emulate ios”.
To build apps for production you must run
“cordova build --release android”
then navigate to project folder platforms/android/ant-build/ and generate a key to sign app -
“keytool -genkey -v -keystore starter-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000”
and sign your application -
“jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore starter-release-key.keystore CordovaApp-release-unsigned.apk alias_name”.
To optimize your apk you should run
“zipalign -v 4 CordovaApp-release-unsigned.apk TutorialApp.apk”
and you will be ready for publishing the file TutorialApp.apk in Google Play. You can find more information about publishing available here.
In the next part of this series I will show how to integrate user authentication in your app with Drupal session login.