SlideShare ist ein Scribd-Unternehmen logo
1 von 33
Building a cross-platform Hybrid
Ionic App with TypeScript
Lessons learned in building a real-world hybrid application using the
Ionic framework and TypeScript
Oleksandr Zinchenko [Macaw], Serge van den Oever [Macaw]
Versions used
This document is produced when using the following versions:
• Cordova version 4.1.2 (cordova --version)
• Ionic version 1.2.8 (ionic --version)
• Ionic framework version 1.0.0-beta.11 (ionic lib)
Contents
1. Introduction
2. Minimal Ionic project structure
3. Create a project
4. Project modifications: initial
structure
5. Project modifications: npm
packages
6. Project modifications: shellinit
7. Project modifications: hooks
8. Project modifications: TypeScript
interfaces
9. Project modifications: TypeScript
compiler
10.Working with Typescript
11.app.ts template
12.Controller template
13.Service template
14.Directive template
15.Restore existing project from
source control
16.Running app
17.Debugging
18.Development tools
19.Accessing the file system
20.Development strategy
21.Best coding practices
22.Debug/release code compilation
23.Preparing for the store: Android
24.Preparing for the store: iOS
25.Update the app without store
approval
26.Optimization tips
27.Ionic/Angular issues (1)
28.Ionic/Angular issues (2)
29.References
Introduction
TypeScript.
TypeScript is a strict superset of JavaScript, and adds optional static
typing and class-based object-oriented programming to the language.
It is designed for development of large applications and transcompiles to
JavaScript.
Additional features include:
1) Type annotations and compile-time type checking
2) Interfaces
3) Classes
4) Modules
5) Abbreviated "arrow" syntax for anonymous functions
Cordova.
Apache Cordova is a set of device APIs that allow to access native device
function from JavaScript. Combined with a UI framework this allows to
create cross-platform app using just HTML, CSS and JavaScript.
Cordova command-line interface (cli) includes:
1) create template Cordova project
2) build app for target platform using the same source code
3) run app in an emulator or device
Angular.
AngularJS lets you write client-side single-page web applications using
JavaScript. Its goal is to simplify both development and testing of an app
by providing a framework for client-side model-view-controller (MVC)
architecture.
Most important concepts in AngularJS:
1) Services
2) Controllers
3) Directives
Ionic.
Ionic is an open source front-end SDK (CSS framework and a Javascript
UI library) for developing hybrid mobile apps with HTML5. Ionic Javascript
UI library is built on top of angular and cordova. The Ionic framework
introduces its own command-line interface (cli) on top of the Cordova cli.
Ionic cli extends Cordova cli with:
1) livereload - reload app immediately after code changes
2) packaging for store deployment – certificates
3) build in the cloud - build for iOS on Windows
4) Gulp build system and the Bower package manager
The purpose of the current presentation is to show the complete developing
cycle of a cross-platform hybrid app using Cordova, Angular, Ionic
and TypeScript.
Minimal Ionic project structure
The following folders and files would be created in new project:
hooks - used to “hook in” actions during the different stages of the Ionic (or actually Cordova) build process
node_modules - project specific node.js modules
plugins - Cordova plugins are located here
scss - the sass files are managed here, builds to css (we move this folder into www to enable css debugging based
on generated map files in the sass compilation)
www - the actual folder where the source code for our app lives. The www folder contains all files that are packaged
into the native host application. All other folders and files are there to support the build process of the native
application, or contains sources compiled into the www folder (like the scss folder, which we move into www).
Ionic uses two package management systems:
• npm - for node packages, useful for installing packages to extends the build process
• packages required are managed through package.json
• packages are installed in the folder node_modules
• Bower - managing client-side libraries
• .bowerrc contains the Bower configuration: { "directory": “www/lib" }
all client-side library packages are installed in www/lib
• packages required are managed through bower.json
gulpfile.js is the “makefile” for the Gulp build system
config.xml is the Cordova configuration file that is used in building the hybrid app
Create a project
1. Use either Windows, OSX or Linux (We only tested on Windows and OSX)
2. Make sure that node.js is installed (see http://nodejs.org/)
3. install the node package cordova and ionic globally using the node.js package manager:
>npm install cordova -g (or update if already installed)
>npm install ionic -g (or update if already installed)
4. Create ionic project:
>ionic start myapp blank --appname "My App" –id com.mycompany.myapp --sass
5. where:
myapp is the folder created in the current folder for your project
blank is the template used for the project
--appname specifies the name of the app
--id specifies the package name (internal name)
--sass specifies to use SASS for CSS precompiling
6. Add target platform (do: > ionic platform list for available platforms on your OS):
>ionic platform add <PLATFORM>
Project modifications: initial structure
1. Move the folder scss into the folder www. All sources that are compiled should we in the www
folder, so source maps can point to the original source files while debugging.
2. Change gulpfile.js so the sass folder points to the www/scss folder:
var paths = {sass: ['./www/scss/**/*.scss']};
3. Change gulpfile.js so the 'sass' task also points to the www/scss folder:
gulp.src('./www/scss/ionic.app.scss')
4. Add the folders used by the package managers www/lib, node_modules, plugins, platforms
to the .gitignore file (Gist).
All external packages, plugins and platforms should not be managed in source control.
5. When working on Windows and using Visual Studio, it is important to mark the node_modules
folder as hidden to avoid issues in Visual Studio which can’t handle deep folder structures
correctly.
6. When working in Visual Studio it is recommended that each project member create his own
solution file to be able to use different path to the project. *.suo files should be excluded from
source control.
Project modifications: npm packages
We also install the Cordova and Ionic packages locally inside the project folder so we can
ensure specific versions of Ionic and Cordova for the project.
> npm install cordova --save-dev
> npm install ionic --save-dev
Use the --save-dev option to register the packages as dependency, so they can be
pulled in later using npm install. The information about packages would be written into
package.json file (initially this file created by ionic start command).
Initially the above commands install the latest versions of Cordova and Ionic. When done
with development lock-down the used versions using the command:
> npm shrinkwrap
Project modifications: shellinit
1) The project specific node packages and their commands are installed in the folder
node_modules/.bin. Add this folder to the PATH (at the beginning) to ensure the usage of the
project specific versions of the packages.
On OSX/Linux add in the file ~/.bash-profile: export PATH=./node_modules/.bin:$PATH
On Windows add file shellinit.bat (Gist) with the following lines:
@rem Add the node_modules.bin folder (found with 'npm bin') to the
path
@cd %~dp0
@for /f %%i in ('npm bin') do set PATH=%%i;%PATH%
On Windows execute the script shellinit.bat before executing command-line commands.
2) In addition you can add the following lines to be sure that all dependent packages will be always installed
by their respective package manager and are up to date:
@rem make sure everything is installed
call npm install
call bower install
call tsd update
call tsd rebundle
call cordova restore plugins --experimental
Project modifications: hooks
When working with a Cordova hybrid app, you might need a way to extend your build process. Cordova Hooks
serves that purpose and can execute scripts before or after certain points of the build process. The obvious
example of hook usage is copying app icons and splash screens to the appropriate platform folder during build
(see more info here).
An example of hook script for copying resources that executes after Cordova’s ‘prepare’ command is
hooksafter_prepare030_resource_files.js (Gist):
#!/usr/bin/env node
var fs = require('fs');
var path = require('path');
var rootdir = process.argv[2];
filestocopy.forEach(function(obj) {
Object.keys(obj).forEach(function(key) {
var val = obj[key];
var srcfile = path.join(rootdir, key);
var destfile = path.join(rootdir, val);
console.log("copying "+srcfile+" to "+destfile);
var destdir = path.dirname(destfile);
if (fs.existsSync(srcfile) && fs.existsSync(destdir)) {
fs.createReadStream(srcfile)
.pipe(fs.createWriteStream(destfile));
}
});
});
var filestocopy = [{
"config/ios/splashscreens/Default-568h@2x~iphone.png":
"platforms/ios/MyApp/Resources/splash/Default-568h@2x~iphone.png"
}, {
"config/ios/splashscreens/Default-Landscape@2x~ipad.png":
"platforms/ios/MyApp/Resources/splash/Default-Landscape@2x~ipad.png"
}, {
"config/ios/splashscreens/Default-Landscape~ipad.png":
"platforms/ios/MyApp/Resources/splash/Default-Landscape~ipad.png"
}, {
"config/ios/splashscreens/Default-Portrait@2x~ipad.png":
"platforms/ios/MyApp/Resources/splash/Default-Portrait@2x~ipad.png"
}, {
"config/ios/splashscreens/Default-Portrait~ipad.png":
"platforms/ios/MyApp/Resources/splash/Default-Portrait~ipad.png"
}, {
"config/ios/splashscreens/Default@2x~iphone.png":
"platforms/ios/MyApp/Resources/splash/Default@2x~iphone.png"
}, {
"config/ios/splashscreens/Default~iphone.png":
"platforms/ios/MyApp/Resources/splash/Default~iphone.png"
}];
Project modifications: TypeScript interfaces
A large set of type definitions for common JavaScript libraries is managed by the DefinitlyTyped interfaces
library. In order to be able to install definitely typed interfaces (definitions) you can use the TypeScript
Definition Manager (tsd):
1. Install tsd locally (0.6.0-beta.4 or greater):
>npm install tsd@next --save-dev
At the time of writing tsd@next was a beta version. Later you should be able to install it using:
>npm install tsd -–save-dev
2. Install all needed type definitions. For example all cordova plugins definitions:
>cd www
>tsd install cordova/* --save –overwrite
--save –overwrite flags will save a list of installed definitions in tsd.json.
3. Add the tsd.json file to source control. Exclude the typings folder (wwwtypings) from source control.
It is possible to update or restore all definitions files configured in tsd.json by:
> tsd reinstall
> tsd rebundle - create the tsd.d.ts file included by _reference.ts
Project modifications: TypeScript compiler
1. In order to be able to compile TypeScript into JavaScript we need to install the gulp-tsc npm module:
> npm install gulp-tsc —save-dev
2. In the default Ionic gulpfile.js add the following bold lines to support TypeScript compilation (Gist):
var typescript = require('gulp-tsc');
var paths = {
sass: ['./www/scss/**/*.scss'],
typescript: ['./www/scripts/**/*.ts']
};
gulp.task('default', ['sass', 'compile']);
function compileTypeScript(done) {
gulp.src(paths.typescript)
.pipe(typescript({ sourcemap: true, out: 'tslib.js', sourceRoot: '../scripts' }))
.pipe(gulp.dest('./www/js/'))
.on('end', done);
}
gulp.task('compile', compileTypeScript);
gulp.task('watch', function() {
compileTypeScript();
gulp.watch(paths.sass, ['sass']);
gulp.watch(paths.typescript, ['compile']);
});
3. The above additions compile all TypeScript files in the www/scripts folder to a single file www/js/tslib.js. Include this resulting JavaScript file in
index.html:
<script src="js/tslib.js"></script>
Working with Typescript
1. Each TypeScript file should begin with the line:
/// <reference path='../_reference.ts'/>
Using this reference all TypeScript files ‘know’ about each other, and editors like Visual Studio
can provide intellisense.
2. Create a _reference.ts file in the www/scripts. This file should contain references to all
theTypeScript files in the project: typings, services, controllers, directives, interfaces and of
course the main entrypoint of the app, app.ts:
/// <reference path='../typings/tsd.d.ts' />
/// <reference path="controllers/MyController.ts" />
/// <reference path="services/MyService.ts" />
/// <reference path="directives/MyDirective.ts" />
/// <reference path="interfaces/MyInterface.ts" />
/// <reference path="app.ts" />
Note that the file ../typings/tsd.d.ts is generated and maintained by the tsd tool.
app.ts template
app.ts is the entry point of the app (Gist).
1. Add reference to _reference.ts:
/// <reference path="_reference.ts"/>
2. We declare an interface for the global rootScope object
$rootScope:
interface IAppRootScopeService extends
ng.IRootScopeService {
online: boolean;
lastScrollTimestamp: number;
isScrolling: () => boolean;
onScroll: () => void;
}
3. Directives are registered using angular.module() calls:
var myApp: ng.IModule = angular.module("angularApp", [
"ngSanitize",
"ionic",
"directive.bindonce",
]);
4. Services should be registered using myApp.service() calls:
myApp.service("serviceName",
myNameSpace.MyServiceClassName);
5. Controllers should be registered in the UI-routing structure (Learn
more here: https://github.com/angular-ui/ui-router).
myApp.config(($stateProvider, $urlRouterProvider) => {
$stateProvider.state("view", {
url: "/view",
templateUrl: "views/view.html",
controller: "ViewController"
});
});
6. Actual code entry point of the app is myApp.run():
myApp.run(
function (
$rootScope: ft.IAppRootScopeService
) {
// myApp entry point
}
);
Controller template
1) Add reference in _reference.ts
2) Bind in app.ts to angular UI-router state:
.state(‘home', {
templateUrl: "views/home.html",
controller: “MyController”
});
/// <reference path='../_reference.ts'/>
interface IMyControllerScope extends ng.IScope {
vm: IMyController; // now our view model (vm) in the scope is typed
}
interface IMyController {
myString: string;
myFunction: (arg) => boolean;
}
class MyController implements IMyController {
myString: string = ‘initial value’;
// $inject annotation. It provides $injector with information about dependencies to be injected into constructor
// it is better to have it close to the constructor, because the parameters must match in count and type.
// See http://docs.angularjs.org/guide/di
public static $inject = [
"$scope",
"$rootScope“
];
constructor(
private $scope: IMyControllerScope,
private $rootScope: IAppRootScopeService
) {
var currentClass: MyController = this;
$scope.vm = this;
$scope.$on("$destroy", () => {
// Clean up detached Dom elements
// Clean up attached listeners
});
currentClass.myString = 'assigning variables here';
}
myFunction(arg): boolean {
// arg processing here
return true;
}
}
Gist of the template
Service template
/// <reference path='../_reference.ts'/>
module myNameSpace {
"use strict";
export class MyServiceClassName {
public static $inject = [
"$log"
];
public pubVar: string;
private privVar: string;
constructor(
private $log: ng.ILogService
) {
privVar = ‘5’;
}
someFunction(element): number {
return parseInt(privVar, 10);
}
}
}
Register a service:
1) Add reference in _reference.ts
2) Register in app.ts:
var myApp: ng.IModule = angular.module("angularApp",
[
"ngSanitize",
"ionic",
"directive.bindonce",
]);
myApp.service(“serviceName", myNameSpace.MyServiceClassName);
Gist of the template
Note that we’re creating a service inside myNameSpace name space. This kind of structure is useful for big proje
cts. As an example you can redefine some interface inside a certain namespace and it will not affect the code out
side this name space.
Directive template
/// <reference path='../../typings/angularjs/angular.d.ts' />
interface IMyDirectiveScope extends ng.IScope {
bookmarker: string;
}
angular.module('directive.bindonce', [])
.directive('bindOnce', function () {
return {
restrict: 'A',
scope: true,
link: ($scope: IMyDirectiveScope): void => {
setTimeout(() => {
$scope.$destroy();
}, 0);
}
}
});
Register a directive:
1) Add reference in _reference.ts
2) Register in app.ts file:
var myApp: ng.IModule = angular.module("angularApp",
[
"ngSanitize",
"ionic",
"directive.bindonce",
]);
Nota bene: Always use functions for your directive definitions. See: http://discventionstech.wordpress.com/2014/01/19/wri
te-angularjs-code-using-typescript/
Gist of the bind-once directive
Restore existing project from source control
1. Update/install node.js (http://nodejs.org/)
2. Pull existing project
3. >cd root_directory_of_the_project
4. >shellinit.bat - This script configures settings for command-line development with local node_modules and
automatically runs:
npm install – reads package.json file and installs listed packages and dependencies
bower install – reads bower.json file and installs listed JavaScript libraries
tsd update – reads tsd.json and installs TypeScript interfaces
tsd rebundle – create tsd.d.ts file which is included to the project for references to TypeScript interfaces
cordova restore plugins --experimental – reads the Cordova config.xml and installs listed plugins
5. When working on Windows AND using Visual Studio, it is important to mark the node_modules folder as hidden to
avoid issues in Visual Studio which can’t handle deep folder structures correctly.
6. >ionic platform add <PLATFORM> - Adds target platform and copies installed plugins.
Running app
To run the app on Android device:
1) enable usb debugging on your device (see tutorial)
2) install OEM USB Drivers (see docs)
3) >gulp – to build the project
4) >ionic run android – to run app from device’s file system
>ionic run android ––livereload – to run app in remote server and access it from your device.
Changing any of the source files will result in an immediate compilation and reload of the app. This option is
extremely useful during development and debugging.
To run the app on Genymotion Android emulator:
1) disable hyper-v (see tutorial)
2) install genymotion Android emulator (http://www.genymotion.com)
3) >ionic run android or >ionic run android –livereload (note that for Genymotion you
should use >ionic run instead of ionic emulate)
To run the app on IOS device
//to do
To run the app on IOS emulator
//to do
To run the app in PC browser (without Cordova support):
>ionic serve – same as run --livereload but this time without Cordova and in the desktop browser.
Debugging
1) Android chrome debugging (Android version 4.4+)
The app uses a web browser component running the Cordova api to
communicate with native features of the device or emulator. The app can be
debugged using the Chrome browser. The Chrome browser allows to connect
remotely (url: chrome://inspect/#devices) to the app running on an
android device or emulator using usb debugging. Note that this approach is
not possible if you have an Android version less than 4.4.
2) IOS safari debugging
//to do
Development tools
Windows:
1) Visual Studio as an editor
2) Genymotion android emulator
3) ConEmu - Windows terminal supporting multiple tabs
4) TotalCommander with ADB plugin to get access to the file system of
the device or emulator
OSX:
WebStorm
iFunBox
Accessing the file system
Files on a device could be accessed for read and write using org.apache.cordova.file plugin. As of
v1.2.0, URLs to important file-system directories are provided as constants which make it extremely
convenient, because file system on different platforms vary significantly. As an example the path to
the application directory in the code looks like
var path = cordova.file.applicationDirectory for both Android and iOS, but the actual
value of path variable would be different.
It is important to know that:
1) >ionic serve – doesn’t use Cordova at all and runs in desktop browser only. This command
creates a small webserver which runs the app. To read files you can use $http requests.
2) >ionic run <PLATFORM>
>ionic emulate <PLATFORM> - these runs will actually install the app on the device (or
emulator) and you will have full access to the file system and app files via the cordova.file
plugin.
3) >ionic run <PLATFORM> --livereload
>ionic emulate <PLATFORM> --livereload
these commands create a remote livereload webserver and access it from the browser component in
the app. You do have access to device’s file system with the cordova.file plugin here, but you
can not access the HTML, JavaScript and CSS files embedded in the app.
Development strategy
1) Start with browser based (w/o Cordova) development using Chrome, simulate device
functionality where possible
• Fast development cycle (>ionic serve)
• Full Chrome debugging power
• Possible to release app preview as an url accessible on dropbox or other location
2) To develop interactions with a device we should use livereload approach using a real device or
an emulator (>ionic run <PLATFORM> --livereload)
3) Develop for Android, test on iOS
• From Android 4.4 full remote debugging and profiling through Chrome inspect
• iOS debugging is “suboptimal”
4) Test for the correct css layout on different devices for every platform.
5) Test JavaScript functionallity of the app in different platforms. The behaviour might be different
(As an example: not all Cordova plugins are cross-platform).
Best coding practices
1. Don’t use ‘this’ pointer directly in a code as it is misleading and most likely will produce
scope-related errors(in case of nested functions). Instead you should assign value of ‘this’
pointer to a definitly typed variable:
var currentClass: ClassName = this;
2. Use types for all variables and functions as it helps to find type missmach.
3. Read best coding practices for TypeScript.
4. Read angularJS ‘style guide’ which contain the best coding practices for angular.
Debug/release code compilation
In order to place the app into the web store it is recommended to:
1.minify HTML, CSS and JavaScript code
2.uglify JavaScript code
3.remove all comments from HTML, CSS and JavaScript
Install ready to use gulp modules that could perform these tasks:
1.>npm install gulp-ng-annotate -–save-dev
used to remove angularJS injections and comments and minifies
JavaScript
2.>npm install gulp-uglify –save-dev
3.>npm install gulp-sync –save-dev
helper module that is used to make sync calls of the tasks in Gulp
4.>npm install gulp-minify-html –save-dev
5.>npm install gulp-rename –save-dev
used to change file name
It is convinient to add these tasks to project gulpfile.js (see full gulpfile.js
at Gist):
var ngAnnotate = require('gulp-ng-annotate');
var uglify = require("gulp-uglify");
var gulpsync = require('gulp-sync')(gulp);
var minifyHTML = require('gulp-minify-html');
var rename = require("gulp-rename");
gulp.task('compile', compileTypeScript);
gulp.task('default', ['debug']);
gulp.task('release', gulpsync.sync(['minifyHtml', 'sass',
'compile', 'minifyJs']));
gulp.task('debug', ['sass', 'compile']);
gulp.task('minifyJs', function (done) {
gulp.src('./www/js/tslib.js')
.pipe(ngAnnotate({remove: true, add: true, single_quotes:
true}))
.pipe(uglify())
.pipe(gulp.dest('./www/js'))
.on('end', done);
});
gulp.task('minifyHtml', function (done) {
gulp.src('./www/index.html')
.pipe(minifyHTML({ empty: true }))
.pipe(rename(function (path) { path.basename += "-min"; }))
.pipe(gulp.dest('./www'));
gulp.src('./www/views/*')
.pipe(minifyHTML({ empty: true }))
.pipe(gulp.dest('./www/views/min'))
.on('end', done);
});
Now it’s much easier to compile debug/release versions of your code:
>gulp debug
>gulp release
Preparing for the store: Android
Before publishing it is necessary to:
1. increase android-versionCode in project/config.xml
file
2. Build:
>cordova build –release
3. sign the App with jarsigner (a part of Java SE
Development Kit)
4. allign the App with zipalign (a part of Android SDK)
It is convinient to write nodejs script ‘build.js’ that will
handle all mentioned tasks:
function shellExec(cmd, callback){
console.log(cmd + ' executing...');
exec(cmd, function(err, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (err !== null) {
console.error('fatal Error: ' + err);
process.exit(1);
} else {
typeof callback === 'function' && callback();
}
});
}
shellExec('cordova build --release android', function ()
{
shellExec('jarsigner -verbose -sigalg SHA1withRSA -
digestalg SHA1 –keystore <PATH_TO_KEYSTORE>
<PATH_TO_release-unsigned.apk> -storepass <PASSWORD>
elsevierMyApp', function() {
shellExec('zipalign -v 4 <PATH_TO_release-
unsigned.apk> <OUTPUT_APK_PATH>');
});
});
usage: >gulp build
Preparing for the store: iOS
//to do
Update the app without store approval
Why it’s important to avoid web store approval?
1) First of all it’s important because people which were not directly involved with developing could update a
content.
2) Second reason is that verifying a new release could take enormous amount of time for some platforms (up
to 10 days for iOS).
The idea is to build a hybrid app that will be a wrapper (bootstrapper app) for an actual App (embedded app).
Bootstrapper app should be configured (name, icons, splash) as it is embedded app and during the run it
should redirect to the actual embedded app. Luckily it is easy to do using javaScript window.location
command.
Bootstrapper app contains:
1) bootstrapper files
2) platform specific cordova.zip file with archived Cordova and plugins
3) embedded app archived into www.zip file
4) content.zip archive containing additional app content
During each start bootstrapper compares version file version.json in the app folder with version file on a
remote server. If updates found bootstrapper detects it and installs new version of the embedded app or
installs new content.
Source code for the bootstrapper you could find at Git, flow diagram you can fins in the blogpost . (Note that
this version still uses old cordova.file plugin conventions for device file system)
Optimization tips
1. Only release versions of the app should be published
2. Exclude console output in release version of the app
3. AngularJS ng-repeat might significantly slow down a hybrid app. Critical case is when each ng-
repeat item contain other angular bindin(s)
4. Minimize amount of angular bindings in HTML code
5. Allways manually unregister Jquery listeners at onDestroy event as angular don’t do it
automatically
6. Allways manually clean all detached DOM elements at onDestroy event as angular don’t do it
automatically
7. Use bind-once bindings if you don’t expect binded value to be changed (see directive template)
8. Starting from angularJS v1.3.5 It is possible to turn off angular debug data (see docs)
Ionic/Angular issues (1)
• Ionic scroll (overflow-scroll=“false”) gives problem with
$ionicScrollDelegate.scrollTo() function. We solve it by using native scrolling
(overflow-scroll=“true”)
• Tap during scroll issue. Touching of a list item during scroll process results in firing touch event of
another item. This bug could be solved by using scroll detection $ionicScrollDelegate.on-
scroll or by creating a directive in case of overflow-scroll=“false”:
angular.module('directive.scrolldetector', [])
.directive('scrollDetector', function ($window) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
function handler(e) {
scope.$evalAsync(function () {
scope.$eval((<any>attrs).scrollDetector);
});
}
scope.$on('$destroy', () => {
element[0].removeEventListener("scroll", handler);
});
element[0].addEventListener("scroll", handler);
}
}
});
Next create function that we can call to check if scrolling is active:
$rootScope.onScroll = () => {
$rootScope.lastScrollTimestamp = (new Date()).getTime();
}
$rootScope.isScrolling = () => {
//to be sure that at least 300 ms we have no scrolling
if ($rootScope.lastScrollTimestamp + 300 > (new Date()).getTime()) {
return true;
} else {
return false;
}}
usage:
in html: <ion-content overflow-scroll="true" scroll-detector="onScroll()">
in script: onTap = (e) => {
if (typeof $rootScope.isScrolling == 'function' && !$rootScope.isScrolling()) {
//tap event here
}}
Ionic/Angular issues (2)
• Angular digest loop and $ionicLoading sync issue. Let’s imagine that you want to use $ionicLoading mesage
right before script start heavy calculation. You will probably write the following:
$ionicLoading.show({ template: ‘wait…’, noBackdrop: true });
//script for heavy calc
which will result in heavy calc first and only then you will see your message. Next you will probably add
timeout wrapper to push your heave calc script call to digest loop right after $ionicLoading.show call:
$ionicLoading.show({ template: ‘wait…’, noBackdrop: true });
$timeout(()={
//script for heavy calc
});
which results with the same problem. We don’t know the clean way to solve the issue and as a workaround
we use this:
$ionicLoading.show({ template: ‘wait…’, noBackdrop: true });
$timeout(()={
//script for heavy calc
}, 300);
References
1. http://nodejs.org/
2. https://angularjs.org/
3. https://github.com/angular-ui/ui-
router
4. http://ionicframework.com/
5. http://www.typescriptlang.org/
6. http://cordova.apache.org/
7. http://plugins.cordova.io/#/
8. http://www.genymotion.com/
9. https://conemu.codeplex.com/
10. http://www.totalcmd.net/plugring/an
droid_adb.html
The end.

Weitere ähnliche Inhalte

Was ist angesagt?

Creating an hybrid app in minutes with Ionic Framework
Creating an hybrid app in minutes with Ionic FrameworkCreating an hybrid app in minutes with Ionic Framework
Creating an hybrid app in minutes with Ionic FrameworkJulien Renaux
 
Cross Platform Mobile Apps with the Ionic Framework
Cross Platform Mobile Apps with the Ionic FrameworkCross Platform Mobile Apps with the Ionic Framework
Cross Platform Mobile Apps with the Ionic FrameworkTroy Miles
 
Creating mobile apps - an introduction to Ionic (Engage 2016)
Creating mobile apps - an introduction to Ionic (Engage 2016)Creating mobile apps - an introduction to Ionic (Engage 2016)
Creating mobile apps - an introduction to Ionic (Engage 2016)Mark Leusink
 
Ionic CLI Adventures
Ionic CLI AdventuresIonic CLI Adventures
Ionic CLI AdventuresJuarez Filho
 
Introduction to Ionic framework
Introduction to Ionic frameworkIntroduction to Ionic framework
Introduction to Ionic frameworkShyjal Raazi
 
Workshop on Hybrid App Development with Ionic Framework
Workshop on Hybrid App Development with Ionic FrameworkWorkshop on Hybrid App Development with Ionic Framework
Workshop on Hybrid App Development with Ionic FrameworkAayush Shrestha
 
Ionic Crash Course! Hack-a-ton SF
Ionic Crash Course! Hack-a-ton SFIonic Crash Course! Hack-a-ton SF
Ionic Crash Course! Hack-a-ton SFLukas Ruebbelke
 
Hybrid Mobile Development with Apache Cordova and Java EE 7 (JavaOne 2014)
Hybrid Mobile Development with Apache Cordova and Java EE 7 (JavaOne 2014)Hybrid Mobile Development with Apache Cordova and Java EE 7 (JavaOne 2014)
Hybrid Mobile Development with Apache Cordova and Java EE 7 (JavaOne 2014)Ryan Cuprak
 
Cordova: APIs and instruments
Cordova: APIs and instrumentsCordova: APIs and instruments
Cordova: APIs and instrumentsIvano Malavolta
 
Cordova + Ionic + MobileFirst
Cordova + Ionic + MobileFirstCordova + Ionic + MobileFirst
Cordova + Ionic + MobileFirstRaymond Camden
 
React Native for ReactJS Devs
React Native for ReactJS DevsReact Native for ReactJS Devs
React Native for ReactJS DevsBarak Cohen
 

Was ist angesagt? (20)

Creating an hybrid app in minutes with Ionic Framework
Creating an hybrid app in minutes with Ionic FrameworkCreating an hybrid app in minutes with Ionic Framework
Creating an hybrid app in minutes with Ionic Framework
 
Ionic Framework
Ionic FrameworkIonic Framework
Ionic Framework
 
Ionic 2 intro
Ionic 2   introIonic 2   intro
Ionic 2 intro
 
Cross Platform Mobile Apps with the Ionic Framework
Cross Platform Mobile Apps with the Ionic FrameworkCross Platform Mobile Apps with the Ionic Framework
Cross Platform Mobile Apps with the Ionic Framework
 
Hybrid app development with ionic
Hybrid app development with ionicHybrid app development with ionic
Hybrid app development with ionic
 
Creating mobile apps - an introduction to Ionic (Engage 2016)
Creating mobile apps - an introduction to Ionic (Engage 2016)Creating mobile apps - an introduction to Ionic (Engage 2016)
Creating mobile apps - an introduction to Ionic (Engage 2016)
 
Ionic CLI Adventures
Ionic CLI AdventuresIonic CLI Adventures
Ionic CLI Adventures
 
Workshop Ionic Framework - CC FE & UX
Workshop Ionic Framework - CC FE & UXWorkshop Ionic Framework - CC FE & UX
Workshop Ionic Framework - CC FE & UX
 
Introduction to Ionic framework
Introduction to Ionic frameworkIntroduction to Ionic framework
Introduction to Ionic framework
 
Workshop on Hybrid App Development with Ionic Framework
Workshop on Hybrid App Development with Ionic FrameworkWorkshop on Hybrid App Development with Ionic Framework
Workshop on Hybrid App Development with Ionic Framework
 
Ionic Framework
Ionic FrameworkIonic Framework
Ionic Framework
 
Ionic Crash Course! Hack-a-ton SF
Ionic Crash Course! Hack-a-ton SFIonic Crash Course! Hack-a-ton SF
Ionic Crash Course! Hack-a-ton SF
 
Ionic Framework
Ionic FrameworkIonic Framework
Ionic Framework
 
Hybrid Mobile Development with Apache Cordova and Java EE 7 (JavaOne 2014)
Hybrid Mobile Development with Apache Cordova and Java EE 7 (JavaOne 2014)Hybrid Mobile Development with Apache Cordova and Java EE 7 (JavaOne 2014)
Hybrid Mobile Development with Apache Cordova and Java EE 7 (JavaOne 2014)
 
Ionic2
Ionic2Ionic2
Ionic2
 
React JS
React JSReact JS
React JS
 
Cordova: APIs and instruments
Cordova: APIs and instrumentsCordova: APIs and instruments
Cordova: APIs and instruments
 
Cordova + Ionic + MobileFirst
Cordova + Ionic + MobileFirstCordova + Ionic + MobileFirst
Cordova + Ionic + MobileFirst
 
React Native for ReactJS Devs
React Native for ReactJS DevsReact Native for ReactJS Devs
React Native for ReactJS Devs
 
Cross-Platform Development
Cross-Platform DevelopmentCross-Platform Development
Cross-Platform Development
 

Andere mochten auch

Building Mobile Applications with Ionic
Building Mobile Applications with IonicBuilding Mobile Applications with Ionic
Building Mobile Applications with IonicMorris Singer
 
Building Mobile Apps with Cordova , AngularJS and Ionic
Building Mobile Apps with Cordova , AngularJS and IonicBuilding Mobile Apps with Cordova , AngularJS and Ionic
Building Mobile Apps with Cordova , AngularJS and IonicKadhem Soltani
 
Ionic 2: The Power of TypeScript
Ionic 2:  The Power of TypeScriptIonic 2:  The Power of TypeScript
Ionic 2: The Power of TypeScriptJacob Orshalick
 
Hybrid Apps with Angular & Ionic Framework
Hybrid Apps with Angular & Ionic FrameworkHybrid Apps with Angular & Ionic Framework
Hybrid Apps with Angular & Ionic FrameworkCihad Horuzoğlu
 
Building Flexible SharePoint Solutions with AngularJS
Building Flexible SharePoint Solutions with AngularJSBuilding Flexible SharePoint Solutions with AngularJS
Building Flexible SharePoint Solutions with AngularJSbgerman
 
Zend PHP 5.3 Demo Certification Test
Zend PHP 5.3 Demo Certification TestZend PHP 5.3 Demo Certification Test
Zend PHP 5.3 Demo Certification TestCarlos Buenosvinos
 
Practical management of development & QA environments for SharePoint 2013
Practical management of development & QA environments for SharePoint 2013Practical management of development & QA environments for SharePoint 2013
Practical management of development & QA environments for SharePoint 2013SharePointRadi
 
Exploring the SharePoint 2013 Community Site Template
Exploring the SharePoint 2013 Community Site TemplateExploring the SharePoint 2013 Community Site Template
Exploring the SharePoint 2013 Community Site TemplateSusan Hanley
 
Ionic 2: Mobile apps with the Web
Ionic 2: Mobile apps with the WebIonic 2: Mobile apps with the Web
Ionic 2: Mobile apps with the WebMike Hartington
 
Synergy Hub - help us create one of the coolest working spaces in Europe!
Synergy Hub - help us create one of the coolest working spaces in Europe!Synergy Hub - help us create one of the coolest working spaces in Europe!
Synergy Hub - help us create one of the coolest working spaces in Europe!Mihai Dragomirescu
 
Hybrid mobile and Ionic
Hybrid mobile and IonicHybrid mobile and Ionic
Hybrid mobile and IonicLiju Pillai
 
Collab365 Global Summit Slides
Collab365 Global Summit SlidesCollab365 Global Summit Slides
Collab365 Global Summit SlidesRick Van Rousselt
 
European SharePoint Conference - TH3
European SharePoint Conference - TH3European SharePoint Conference - TH3
European SharePoint Conference - TH3Rick Van Rousselt
 
Session Slides from DEVintersection Europe
Session Slides from DEVintersection EuropeSession Slides from DEVintersection Europe
Session Slides from DEVintersection EuropeRick Van Rousselt
 
Next Gen Portal in Office 365: April 2015. SUGUK
Next Gen Portal in Office 365: April 2015. SUGUKNext Gen Portal in Office 365: April 2015. SUGUK
Next Gen Portal in Office 365: April 2015. SUGUKpearce.alex
 
Mobile HTML5 websites and Hybrid Apps with AngularJS
Mobile HTML5 websites and Hybrid Apps with AngularJSMobile HTML5 websites and Hybrid Apps with AngularJS
Mobile HTML5 websites and Hybrid Apps with AngularJSCarlo Bonamico
 

Andere mochten auch (19)

Building Mobile Applications with Ionic
Building Mobile Applications with IonicBuilding Mobile Applications with Ionic
Building Mobile Applications with Ionic
 
Building Mobile Apps with Cordova , AngularJS and Ionic
Building Mobile Apps with Cordova , AngularJS and IonicBuilding Mobile Apps with Cordova , AngularJS and Ionic
Building Mobile Apps with Cordova , AngularJS and Ionic
 
Ionic 2: The Power of TypeScript
Ionic 2:  The Power of TypeScriptIonic 2:  The Power of TypeScript
Ionic 2: The Power of TypeScript
 
Hybrid Apps with Angular & Ionic Framework
Hybrid Apps with Angular & Ionic FrameworkHybrid Apps with Angular & Ionic Framework
Hybrid Apps with Angular & Ionic Framework
 
Building Flexible SharePoint Solutions with AngularJS
Building Flexible SharePoint Solutions with AngularJSBuilding Flexible SharePoint Solutions with AngularJS
Building Flexible SharePoint Solutions with AngularJS
 
Zend PHP 5.3 Demo Certification Test
Zend PHP 5.3 Demo Certification TestZend PHP 5.3 Demo Certification Test
Zend PHP 5.3 Demo Certification Test
 
Practical management of development & QA environments for SharePoint 2013
Practical management of development & QA environments for SharePoint 2013Practical management of development & QA environments for SharePoint 2013
Practical management of development & QA environments for SharePoint 2013
 
Exploring the SharePoint 2013 Community Site Template
Exploring the SharePoint 2013 Community Site TemplateExploring the SharePoint 2013 Community Site Template
Exploring the SharePoint 2013 Community Site Template
 
Ionic 2: Mobile apps with the Web
Ionic 2: Mobile apps with the WebIonic 2: Mobile apps with the Web
Ionic 2: Mobile apps with the Web
 
Intro to ionic 2
Intro to ionic 2Intro to ionic 2
Intro to ionic 2
 
Synergy Hub - help us create one of the coolest working spaces in Europe!
Synergy Hub - help us create one of the coolest working spaces in Europe!Synergy Hub - help us create one of the coolest working spaces in Europe!
Synergy Hub - help us create one of the coolest working spaces in Europe!
 
Sql Nexus
Sql NexusSql Nexus
Sql Nexus
 
Hybrid mobile and Ionic
Hybrid mobile and IonicHybrid mobile and Ionic
Hybrid mobile and Ionic
 
Collab365 Global Summit Slides
Collab365 Global Summit SlidesCollab365 Global Summit Slides
Collab365 Global Summit Slides
 
European SharePoint Conference - TH3
European SharePoint Conference - TH3European SharePoint Conference - TH3
European SharePoint Conference - TH3
 
Session Slides from DEVintersection Europe
Session Slides from DEVintersection EuropeSession Slides from DEVintersection Europe
Session Slides from DEVintersection Europe
 
Next Gen Portal in Office 365: April 2015. SUGUK
Next Gen Portal in Office 365: April 2015. SUGUKNext Gen Portal in Office 365: April 2015. SUGUK
Next Gen Portal in Office 365: April 2015. SUGUK
 
Mobile HTML5 websites and Hybrid Apps with AngularJS
Mobile HTML5 websites and Hybrid Apps with AngularJSMobile HTML5 websites and Hybrid Apps with AngularJS
Mobile HTML5 websites and Hybrid Apps with AngularJS
 
Microsoft PowerApps Introduction by Usama Wahab Khan MVP
Microsoft PowerApps Introduction by Usama Wahab Khan MVP Microsoft PowerApps Introduction by Usama Wahab Khan MVP
Microsoft PowerApps Introduction by Usama Wahab Khan MVP
 

Ähnlich wie Building an Ionic hybrid mobile app with TypeScript

[Patel] SPFx: An ISV Insight into latest Microsoft's customization model
[Patel] SPFx: An ISV Insight into latest Microsoft's customization model[Patel] SPFx: An ISV Insight into latest Microsoft's customization model
[Patel] SPFx: An ISV Insight into latest Microsoft's customization modelEuropean Collaboration Summit
 
Android ndk - Introduction
Android ndk  - IntroductionAndroid ndk  - Introduction
Android ndk - IntroductionRakesh Jha
 
Pemrograman mobile menggunakan ionic framework
Pemrograman mobile menggunakan ionic frameworkPemrograman mobile menggunakan ionic framework
Pemrograman mobile menggunakan ionic frameworkPuguh Rismadi
 
Magento infrastructure by OpsWay
Magento infrastructure by OpsWayMagento infrastructure by OpsWay
Magento infrastructure by OpsWayOpsWay
 
Cloud native buildpacks_collabnix
Cloud native buildpacks_collabnixCloud native buildpacks_collabnix
Cloud native buildpacks_collabnixSuman Chakraborty
 
node-webkit : Make a magic from your a desktop app to desktop app!
node-webkit : Make a magic from your a desktop app to desktop app!node-webkit : Make a magic from your a desktop app to desktop app!
node-webkit : Make a magic from your a desktop app to desktop app!욱진 양
 
Dev opsec dockerimage_patch_n_lifecyclemanagement_
Dev opsec dockerimage_patch_n_lifecyclemanagement_Dev opsec dockerimage_patch_n_lifecyclemanagement_
Dev opsec dockerimage_patch_n_lifecyclemanagement_kanedafromparis
 
Chris OBrien - Pitfalls when developing with the SharePoint Framework (SPFx)
Chris OBrien - Pitfalls when developing with the SharePoint Framework (SPFx)Chris OBrien - Pitfalls when developing with the SharePoint Framework (SPFx)
Chris OBrien - Pitfalls when developing with the SharePoint Framework (SPFx)Chris O'Brien
 
Native development kit (ndk) introduction
Native development kit (ndk)  introductionNative development kit (ndk)  introduction
Native development kit (ndk) introductionRakesh Jha
 
Docker - Demo on PHP Application deployment
Docker - Demo on PHP Application deployment Docker - Demo on PHP Application deployment
Docker - Demo on PHP Application deployment Arun prasath
 
Tribal Nova Docker feedback
Tribal Nova Docker feedbackTribal Nova Docker feedback
Tribal Nova Docker feedbackNicolas Degardin
 
Phonegap android angualr material design
Phonegap android angualr material designPhonegap android angualr material design
Phonegap android angualr material designSrinadh Kanugala
 
Node JS - A brief overview on building real-time web applications
Node JS - A brief overview on building real-time web applicationsNode JS - A brief overview on building real-time web applications
Node JS - A brief overview on building real-time web applicationsExpeed Software
 
Dockercon EU 2014
Dockercon EU 2014Dockercon EU 2014
Dockercon EU 2014Rafe Colton
 
Magento Docker Setup.pdf
Magento Docker Setup.pdfMagento Docker Setup.pdf
Magento Docker Setup.pdfAbid Malik
 

Ähnlich wie Building an Ionic hybrid mobile app with TypeScript (20)

[Patel] SPFx: An ISV Insight into latest Microsoft's customization model
[Patel] SPFx: An ISV Insight into latest Microsoft's customization model[Patel] SPFx: An ISV Insight into latest Microsoft's customization model
[Patel] SPFx: An ISV Insight into latest Microsoft's customization model
 
Android ndk - Introduction
Android ndk  - IntroductionAndroid ndk  - Introduction
Android ndk - Introduction
 
Pemrograman mobile menggunakan ionic framework
Pemrograman mobile menggunakan ionic frameworkPemrograman mobile menggunakan ionic framework
Pemrograman mobile menggunakan ionic framework
 
Magento infrastructure by OpsWay
Magento infrastructure by OpsWayMagento infrastructure by OpsWay
Magento infrastructure by OpsWay
 
Android NDK
Android NDKAndroid NDK
Android NDK
 
Android ndk
Android ndkAndroid ndk
Android ndk
 
Cloud native buildpacks_collabnix
Cloud native buildpacks_collabnixCloud native buildpacks_collabnix
Cloud native buildpacks_collabnix
 
Microservices in Java
Microservices in JavaMicroservices in Java
Microservices in Java
 
node-webkit : Make a magic from your a desktop app to desktop app!
node-webkit : Make a magic from your a desktop app to desktop app!node-webkit : Make a magic from your a desktop app to desktop app!
node-webkit : Make a magic from your a desktop app to desktop app!
 
CocoaPods.pptx
CocoaPods.pptxCocoaPods.pptx
CocoaPods.pptx
 
Dev opsec dockerimage_patch_n_lifecyclemanagement_
Dev opsec dockerimage_patch_n_lifecyclemanagement_Dev opsec dockerimage_patch_n_lifecyclemanagement_
Dev opsec dockerimage_patch_n_lifecyclemanagement_
 
Chris OBrien - Pitfalls when developing with the SharePoint Framework (SPFx)
Chris OBrien - Pitfalls when developing with the SharePoint Framework (SPFx)Chris OBrien - Pitfalls when developing with the SharePoint Framework (SPFx)
Chris OBrien - Pitfalls when developing with the SharePoint Framework (SPFx)
 
Native development kit (ndk) introduction
Native development kit (ndk)  introductionNative development kit (ndk)  introduction
Native development kit (ndk) introduction
 
Docker - Demo on PHP Application deployment
Docker - Demo on PHP Application deployment Docker - Demo on PHP Application deployment
Docker - Demo on PHP Application deployment
 
Short-Training asp.net vNext
Short-Training asp.net vNextShort-Training asp.net vNext
Short-Training asp.net vNext
 
Tribal Nova Docker feedback
Tribal Nova Docker feedbackTribal Nova Docker feedback
Tribal Nova Docker feedback
 
Phonegap android angualr material design
Phonegap android angualr material designPhonegap android angualr material design
Phonegap android angualr material design
 
Node JS - A brief overview on building real-time web applications
Node JS - A brief overview on building real-time web applicationsNode JS - A brief overview on building real-time web applications
Node JS - A brief overview on building real-time web applications
 
Dockercon EU 2014
Dockercon EU 2014Dockercon EU 2014
Dockercon EU 2014
 
Magento Docker Setup.pdf
Magento Docker Setup.pdfMagento Docker Setup.pdf
Magento Docker Setup.pdf
 

Kürzlich hochgeladen

A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 

Kürzlich hochgeladen (20)

A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 

Building an Ionic hybrid mobile app with TypeScript

  • 1. Building a cross-platform Hybrid Ionic App with TypeScript Lessons learned in building a real-world hybrid application using the Ionic framework and TypeScript Oleksandr Zinchenko [Macaw], Serge van den Oever [Macaw]
  • 2. Versions used This document is produced when using the following versions: • Cordova version 4.1.2 (cordova --version) • Ionic version 1.2.8 (ionic --version) • Ionic framework version 1.0.0-beta.11 (ionic lib)
  • 3. Contents 1. Introduction 2. Minimal Ionic project structure 3. Create a project 4. Project modifications: initial structure 5. Project modifications: npm packages 6. Project modifications: shellinit 7. Project modifications: hooks 8. Project modifications: TypeScript interfaces 9. Project modifications: TypeScript compiler 10.Working with Typescript 11.app.ts template 12.Controller template 13.Service template 14.Directive template 15.Restore existing project from source control 16.Running app 17.Debugging 18.Development tools 19.Accessing the file system 20.Development strategy 21.Best coding practices 22.Debug/release code compilation 23.Preparing for the store: Android 24.Preparing for the store: iOS 25.Update the app without store approval 26.Optimization tips 27.Ionic/Angular issues (1) 28.Ionic/Angular issues (2) 29.References
  • 4. Introduction TypeScript. TypeScript is a strict superset of JavaScript, and adds optional static typing and class-based object-oriented programming to the language. It is designed for development of large applications and transcompiles to JavaScript. Additional features include: 1) Type annotations and compile-time type checking 2) Interfaces 3) Classes 4) Modules 5) Abbreviated "arrow" syntax for anonymous functions Cordova. Apache Cordova is a set of device APIs that allow to access native device function from JavaScript. Combined with a UI framework this allows to create cross-platform app using just HTML, CSS and JavaScript. Cordova command-line interface (cli) includes: 1) create template Cordova project 2) build app for target platform using the same source code 3) run app in an emulator or device Angular. AngularJS lets you write client-side single-page web applications using JavaScript. Its goal is to simplify both development and testing of an app by providing a framework for client-side model-view-controller (MVC) architecture. Most important concepts in AngularJS: 1) Services 2) Controllers 3) Directives Ionic. Ionic is an open source front-end SDK (CSS framework and a Javascript UI library) for developing hybrid mobile apps with HTML5. Ionic Javascript UI library is built on top of angular and cordova. The Ionic framework introduces its own command-line interface (cli) on top of the Cordova cli. Ionic cli extends Cordova cli with: 1) livereload - reload app immediately after code changes 2) packaging for store deployment – certificates 3) build in the cloud - build for iOS on Windows 4) Gulp build system and the Bower package manager The purpose of the current presentation is to show the complete developing cycle of a cross-platform hybrid app using Cordova, Angular, Ionic and TypeScript.
  • 5. Minimal Ionic project structure The following folders and files would be created in new project: hooks - used to “hook in” actions during the different stages of the Ionic (or actually Cordova) build process node_modules - project specific node.js modules plugins - Cordova plugins are located here scss - the sass files are managed here, builds to css (we move this folder into www to enable css debugging based on generated map files in the sass compilation) www - the actual folder where the source code for our app lives. The www folder contains all files that are packaged into the native host application. All other folders and files are there to support the build process of the native application, or contains sources compiled into the www folder (like the scss folder, which we move into www). Ionic uses two package management systems: • npm - for node packages, useful for installing packages to extends the build process • packages required are managed through package.json • packages are installed in the folder node_modules • Bower - managing client-side libraries • .bowerrc contains the Bower configuration: { "directory": “www/lib" } all client-side library packages are installed in www/lib • packages required are managed through bower.json gulpfile.js is the “makefile” for the Gulp build system config.xml is the Cordova configuration file that is used in building the hybrid app
  • 6. Create a project 1. Use either Windows, OSX or Linux (We only tested on Windows and OSX) 2. Make sure that node.js is installed (see http://nodejs.org/) 3. install the node package cordova and ionic globally using the node.js package manager: >npm install cordova -g (or update if already installed) >npm install ionic -g (or update if already installed) 4. Create ionic project: >ionic start myapp blank --appname "My App" –id com.mycompany.myapp --sass 5. where: myapp is the folder created in the current folder for your project blank is the template used for the project --appname specifies the name of the app --id specifies the package name (internal name) --sass specifies to use SASS for CSS precompiling 6. Add target platform (do: > ionic platform list for available platforms on your OS): >ionic platform add <PLATFORM>
  • 7. Project modifications: initial structure 1. Move the folder scss into the folder www. All sources that are compiled should we in the www folder, so source maps can point to the original source files while debugging. 2. Change gulpfile.js so the sass folder points to the www/scss folder: var paths = {sass: ['./www/scss/**/*.scss']}; 3. Change gulpfile.js so the 'sass' task also points to the www/scss folder: gulp.src('./www/scss/ionic.app.scss') 4. Add the folders used by the package managers www/lib, node_modules, plugins, platforms to the .gitignore file (Gist). All external packages, plugins and platforms should not be managed in source control. 5. When working on Windows and using Visual Studio, it is important to mark the node_modules folder as hidden to avoid issues in Visual Studio which can’t handle deep folder structures correctly. 6. When working in Visual Studio it is recommended that each project member create his own solution file to be able to use different path to the project. *.suo files should be excluded from source control.
  • 8. Project modifications: npm packages We also install the Cordova and Ionic packages locally inside the project folder so we can ensure specific versions of Ionic and Cordova for the project. > npm install cordova --save-dev > npm install ionic --save-dev Use the --save-dev option to register the packages as dependency, so they can be pulled in later using npm install. The information about packages would be written into package.json file (initially this file created by ionic start command). Initially the above commands install the latest versions of Cordova and Ionic. When done with development lock-down the used versions using the command: > npm shrinkwrap
  • 9. Project modifications: shellinit 1) The project specific node packages and their commands are installed in the folder node_modules/.bin. Add this folder to the PATH (at the beginning) to ensure the usage of the project specific versions of the packages. On OSX/Linux add in the file ~/.bash-profile: export PATH=./node_modules/.bin:$PATH On Windows add file shellinit.bat (Gist) with the following lines: @rem Add the node_modules.bin folder (found with 'npm bin') to the path @cd %~dp0 @for /f %%i in ('npm bin') do set PATH=%%i;%PATH% On Windows execute the script shellinit.bat before executing command-line commands. 2) In addition you can add the following lines to be sure that all dependent packages will be always installed by their respective package manager and are up to date: @rem make sure everything is installed call npm install call bower install call tsd update call tsd rebundle call cordova restore plugins --experimental
  • 10. Project modifications: hooks When working with a Cordova hybrid app, you might need a way to extend your build process. Cordova Hooks serves that purpose and can execute scripts before or after certain points of the build process. The obvious example of hook usage is copying app icons and splash screens to the appropriate platform folder during build (see more info here). An example of hook script for copying resources that executes after Cordova’s ‘prepare’ command is hooksafter_prepare030_resource_files.js (Gist): #!/usr/bin/env node var fs = require('fs'); var path = require('path'); var rootdir = process.argv[2]; filestocopy.forEach(function(obj) { Object.keys(obj).forEach(function(key) { var val = obj[key]; var srcfile = path.join(rootdir, key); var destfile = path.join(rootdir, val); console.log("copying "+srcfile+" to "+destfile); var destdir = path.dirname(destfile); if (fs.existsSync(srcfile) && fs.existsSync(destdir)) { fs.createReadStream(srcfile) .pipe(fs.createWriteStream(destfile)); } }); }); var filestocopy = [{ "config/ios/splashscreens/Default-568h@2x~iphone.png": "platforms/ios/MyApp/Resources/splash/Default-568h@2x~iphone.png" }, { "config/ios/splashscreens/Default-Landscape@2x~ipad.png": "platforms/ios/MyApp/Resources/splash/Default-Landscape@2x~ipad.png" }, { "config/ios/splashscreens/Default-Landscape~ipad.png": "platforms/ios/MyApp/Resources/splash/Default-Landscape~ipad.png" }, { "config/ios/splashscreens/Default-Portrait@2x~ipad.png": "platforms/ios/MyApp/Resources/splash/Default-Portrait@2x~ipad.png" }, { "config/ios/splashscreens/Default-Portrait~ipad.png": "platforms/ios/MyApp/Resources/splash/Default-Portrait~ipad.png" }, { "config/ios/splashscreens/Default@2x~iphone.png": "platforms/ios/MyApp/Resources/splash/Default@2x~iphone.png" }, { "config/ios/splashscreens/Default~iphone.png": "platforms/ios/MyApp/Resources/splash/Default~iphone.png" }];
  • 11. Project modifications: TypeScript interfaces A large set of type definitions for common JavaScript libraries is managed by the DefinitlyTyped interfaces library. In order to be able to install definitely typed interfaces (definitions) you can use the TypeScript Definition Manager (tsd): 1. Install tsd locally (0.6.0-beta.4 or greater): >npm install tsd@next --save-dev At the time of writing tsd@next was a beta version. Later you should be able to install it using: >npm install tsd -–save-dev 2. Install all needed type definitions. For example all cordova plugins definitions: >cd www >tsd install cordova/* --save –overwrite --save –overwrite flags will save a list of installed definitions in tsd.json. 3. Add the tsd.json file to source control. Exclude the typings folder (wwwtypings) from source control. It is possible to update or restore all definitions files configured in tsd.json by: > tsd reinstall > tsd rebundle - create the tsd.d.ts file included by _reference.ts
  • 12. Project modifications: TypeScript compiler 1. In order to be able to compile TypeScript into JavaScript we need to install the gulp-tsc npm module: > npm install gulp-tsc —save-dev 2. In the default Ionic gulpfile.js add the following bold lines to support TypeScript compilation (Gist): var typescript = require('gulp-tsc'); var paths = { sass: ['./www/scss/**/*.scss'], typescript: ['./www/scripts/**/*.ts'] }; gulp.task('default', ['sass', 'compile']); function compileTypeScript(done) { gulp.src(paths.typescript) .pipe(typescript({ sourcemap: true, out: 'tslib.js', sourceRoot: '../scripts' })) .pipe(gulp.dest('./www/js/')) .on('end', done); } gulp.task('compile', compileTypeScript); gulp.task('watch', function() { compileTypeScript(); gulp.watch(paths.sass, ['sass']); gulp.watch(paths.typescript, ['compile']); }); 3. The above additions compile all TypeScript files in the www/scripts folder to a single file www/js/tslib.js. Include this resulting JavaScript file in index.html: <script src="js/tslib.js"></script>
  • 13. Working with Typescript 1. Each TypeScript file should begin with the line: /// <reference path='../_reference.ts'/> Using this reference all TypeScript files ‘know’ about each other, and editors like Visual Studio can provide intellisense. 2. Create a _reference.ts file in the www/scripts. This file should contain references to all theTypeScript files in the project: typings, services, controllers, directives, interfaces and of course the main entrypoint of the app, app.ts: /// <reference path='../typings/tsd.d.ts' /> /// <reference path="controllers/MyController.ts" /> /// <reference path="services/MyService.ts" /> /// <reference path="directives/MyDirective.ts" /> /// <reference path="interfaces/MyInterface.ts" /> /// <reference path="app.ts" /> Note that the file ../typings/tsd.d.ts is generated and maintained by the tsd tool.
  • 14. app.ts template app.ts is the entry point of the app (Gist). 1. Add reference to _reference.ts: /// <reference path="_reference.ts"/> 2. We declare an interface for the global rootScope object $rootScope: interface IAppRootScopeService extends ng.IRootScopeService { online: boolean; lastScrollTimestamp: number; isScrolling: () => boolean; onScroll: () => void; } 3. Directives are registered using angular.module() calls: var myApp: ng.IModule = angular.module("angularApp", [ "ngSanitize", "ionic", "directive.bindonce", ]); 4. Services should be registered using myApp.service() calls: myApp.service("serviceName", myNameSpace.MyServiceClassName); 5. Controllers should be registered in the UI-routing structure (Learn more here: https://github.com/angular-ui/ui-router). myApp.config(($stateProvider, $urlRouterProvider) => { $stateProvider.state("view", { url: "/view", templateUrl: "views/view.html", controller: "ViewController" }); }); 6. Actual code entry point of the app is myApp.run(): myApp.run( function ( $rootScope: ft.IAppRootScopeService ) { // myApp entry point } );
  • 15. Controller template 1) Add reference in _reference.ts 2) Bind in app.ts to angular UI-router state: .state(‘home', { templateUrl: "views/home.html", controller: “MyController” }); /// <reference path='../_reference.ts'/> interface IMyControllerScope extends ng.IScope { vm: IMyController; // now our view model (vm) in the scope is typed } interface IMyController { myString: string; myFunction: (arg) => boolean; } class MyController implements IMyController { myString: string = ‘initial value’; // $inject annotation. It provides $injector with information about dependencies to be injected into constructor // it is better to have it close to the constructor, because the parameters must match in count and type. // See http://docs.angularjs.org/guide/di public static $inject = [ "$scope", "$rootScope“ ]; constructor( private $scope: IMyControllerScope, private $rootScope: IAppRootScopeService ) { var currentClass: MyController = this; $scope.vm = this; $scope.$on("$destroy", () => { // Clean up detached Dom elements // Clean up attached listeners }); currentClass.myString = 'assigning variables here'; } myFunction(arg): boolean { // arg processing here return true; } } Gist of the template
  • 16. Service template /// <reference path='../_reference.ts'/> module myNameSpace { "use strict"; export class MyServiceClassName { public static $inject = [ "$log" ]; public pubVar: string; private privVar: string; constructor( private $log: ng.ILogService ) { privVar = ‘5’; } someFunction(element): number { return parseInt(privVar, 10); } } } Register a service: 1) Add reference in _reference.ts 2) Register in app.ts: var myApp: ng.IModule = angular.module("angularApp", [ "ngSanitize", "ionic", "directive.bindonce", ]); myApp.service(“serviceName", myNameSpace.MyServiceClassName); Gist of the template Note that we’re creating a service inside myNameSpace name space. This kind of structure is useful for big proje cts. As an example you can redefine some interface inside a certain namespace and it will not affect the code out side this name space.
  • 17. Directive template /// <reference path='../../typings/angularjs/angular.d.ts' /> interface IMyDirectiveScope extends ng.IScope { bookmarker: string; } angular.module('directive.bindonce', []) .directive('bindOnce', function () { return { restrict: 'A', scope: true, link: ($scope: IMyDirectiveScope): void => { setTimeout(() => { $scope.$destroy(); }, 0); } } }); Register a directive: 1) Add reference in _reference.ts 2) Register in app.ts file: var myApp: ng.IModule = angular.module("angularApp", [ "ngSanitize", "ionic", "directive.bindonce", ]); Nota bene: Always use functions for your directive definitions. See: http://discventionstech.wordpress.com/2014/01/19/wri te-angularjs-code-using-typescript/ Gist of the bind-once directive
  • 18. Restore existing project from source control 1. Update/install node.js (http://nodejs.org/) 2. Pull existing project 3. >cd root_directory_of_the_project 4. >shellinit.bat - This script configures settings for command-line development with local node_modules and automatically runs: npm install – reads package.json file and installs listed packages and dependencies bower install – reads bower.json file and installs listed JavaScript libraries tsd update – reads tsd.json and installs TypeScript interfaces tsd rebundle – create tsd.d.ts file which is included to the project for references to TypeScript interfaces cordova restore plugins --experimental – reads the Cordova config.xml and installs listed plugins 5. When working on Windows AND using Visual Studio, it is important to mark the node_modules folder as hidden to avoid issues in Visual Studio which can’t handle deep folder structures correctly. 6. >ionic platform add <PLATFORM> - Adds target platform and copies installed plugins.
  • 19. Running app To run the app on Android device: 1) enable usb debugging on your device (see tutorial) 2) install OEM USB Drivers (see docs) 3) >gulp – to build the project 4) >ionic run android – to run app from device’s file system >ionic run android ––livereload – to run app in remote server and access it from your device. Changing any of the source files will result in an immediate compilation and reload of the app. This option is extremely useful during development and debugging. To run the app on Genymotion Android emulator: 1) disable hyper-v (see tutorial) 2) install genymotion Android emulator (http://www.genymotion.com) 3) >ionic run android or >ionic run android –livereload (note that for Genymotion you should use >ionic run instead of ionic emulate) To run the app on IOS device //to do To run the app on IOS emulator //to do To run the app in PC browser (without Cordova support): >ionic serve – same as run --livereload but this time without Cordova and in the desktop browser.
  • 20. Debugging 1) Android chrome debugging (Android version 4.4+) The app uses a web browser component running the Cordova api to communicate with native features of the device or emulator. The app can be debugged using the Chrome browser. The Chrome browser allows to connect remotely (url: chrome://inspect/#devices) to the app running on an android device or emulator using usb debugging. Note that this approach is not possible if you have an Android version less than 4.4. 2) IOS safari debugging //to do
  • 21. Development tools Windows: 1) Visual Studio as an editor 2) Genymotion android emulator 3) ConEmu - Windows terminal supporting multiple tabs 4) TotalCommander with ADB plugin to get access to the file system of the device or emulator OSX: WebStorm iFunBox
  • 22. Accessing the file system Files on a device could be accessed for read and write using org.apache.cordova.file plugin. As of v1.2.0, URLs to important file-system directories are provided as constants which make it extremely convenient, because file system on different platforms vary significantly. As an example the path to the application directory in the code looks like var path = cordova.file.applicationDirectory for both Android and iOS, but the actual value of path variable would be different. It is important to know that: 1) >ionic serve – doesn’t use Cordova at all and runs in desktop browser only. This command creates a small webserver which runs the app. To read files you can use $http requests. 2) >ionic run <PLATFORM> >ionic emulate <PLATFORM> - these runs will actually install the app on the device (or emulator) and you will have full access to the file system and app files via the cordova.file plugin. 3) >ionic run <PLATFORM> --livereload >ionic emulate <PLATFORM> --livereload these commands create a remote livereload webserver and access it from the browser component in the app. You do have access to device’s file system with the cordova.file plugin here, but you can not access the HTML, JavaScript and CSS files embedded in the app.
  • 23. Development strategy 1) Start with browser based (w/o Cordova) development using Chrome, simulate device functionality where possible • Fast development cycle (>ionic serve) • Full Chrome debugging power • Possible to release app preview as an url accessible on dropbox or other location 2) To develop interactions with a device we should use livereload approach using a real device or an emulator (>ionic run <PLATFORM> --livereload) 3) Develop for Android, test on iOS • From Android 4.4 full remote debugging and profiling through Chrome inspect • iOS debugging is “suboptimal” 4) Test for the correct css layout on different devices for every platform. 5) Test JavaScript functionallity of the app in different platforms. The behaviour might be different (As an example: not all Cordova plugins are cross-platform).
  • 24. Best coding practices 1. Don’t use ‘this’ pointer directly in a code as it is misleading and most likely will produce scope-related errors(in case of nested functions). Instead you should assign value of ‘this’ pointer to a definitly typed variable: var currentClass: ClassName = this; 2. Use types for all variables and functions as it helps to find type missmach. 3. Read best coding practices for TypeScript. 4. Read angularJS ‘style guide’ which contain the best coding practices for angular.
  • 25. Debug/release code compilation In order to place the app into the web store it is recommended to: 1.minify HTML, CSS and JavaScript code 2.uglify JavaScript code 3.remove all comments from HTML, CSS and JavaScript Install ready to use gulp modules that could perform these tasks: 1.>npm install gulp-ng-annotate -–save-dev used to remove angularJS injections and comments and minifies JavaScript 2.>npm install gulp-uglify –save-dev 3.>npm install gulp-sync –save-dev helper module that is used to make sync calls of the tasks in Gulp 4.>npm install gulp-minify-html –save-dev 5.>npm install gulp-rename –save-dev used to change file name It is convinient to add these tasks to project gulpfile.js (see full gulpfile.js at Gist): var ngAnnotate = require('gulp-ng-annotate'); var uglify = require("gulp-uglify"); var gulpsync = require('gulp-sync')(gulp); var minifyHTML = require('gulp-minify-html'); var rename = require("gulp-rename"); gulp.task('compile', compileTypeScript); gulp.task('default', ['debug']); gulp.task('release', gulpsync.sync(['minifyHtml', 'sass', 'compile', 'minifyJs'])); gulp.task('debug', ['sass', 'compile']); gulp.task('minifyJs', function (done) { gulp.src('./www/js/tslib.js') .pipe(ngAnnotate({remove: true, add: true, single_quotes: true})) .pipe(uglify()) .pipe(gulp.dest('./www/js')) .on('end', done); }); gulp.task('minifyHtml', function (done) { gulp.src('./www/index.html') .pipe(minifyHTML({ empty: true })) .pipe(rename(function (path) { path.basename += "-min"; })) .pipe(gulp.dest('./www')); gulp.src('./www/views/*') .pipe(minifyHTML({ empty: true })) .pipe(gulp.dest('./www/views/min')) .on('end', done); }); Now it’s much easier to compile debug/release versions of your code: >gulp debug >gulp release
  • 26. Preparing for the store: Android Before publishing it is necessary to: 1. increase android-versionCode in project/config.xml file 2. Build: >cordova build –release 3. sign the App with jarsigner (a part of Java SE Development Kit) 4. allign the App with zipalign (a part of Android SDK) It is convinient to write nodejs script ‘build.js’ that will handle all mentioned tasks: function shellExec(cmd, callback){ console.log(cmd + ' executing...'); exec(cmd, function(err, stdout, stderr) { console.log('stdout: ' + stdout); console.log('stderr: ' + stderr); if (err !== null) { console.error('fatal Error: ' + err); process.exit(1); } else { typeof callback === 'function' && callback(); } }); } shellExec('cordova build --release android', function () { shellExec('jarsigner -verbose -sigalg SHA1withRSA - digestalg SHA1 –keystore <PATH_TO_KEYSTORE> <PATH_TO_release-unsigned.apk> -storepass <PASSWORD> elsevierMyApp', function() { shellExec('zipalign -v 4 <PATH_TO_release- unsigned.apk> <OUTPUT_APK_PATH>'); }); }); usage: >gulp build
  • 27. Preparing for the store: iOS //to do
  • 28. Update the app without store approval Why it’s important to avoid web store approval? 1) First of all it’s important because people which were not directly involved with developing could update a content. 2) Second reason is that verifying a new release could take enormous amount of time for some platforms (up to 10 days for iOS). The idea is to build a hybrid app that will be a wrapper (bootstrapper app) for an actual App (embedded app). Bootstrapper app should be configured (name, icons, splash) as it is embedded app and during the run it should redirect to the actual embedded app. Luckily it is easy to do using javaScript window.location command. Bootstrapper app contains: 1) bootstrapper files 2) platform specific cordova.zip file with archived Cordova and plugins 3) embedded app archived into www.zip file 4) content.zip archive containing additional app content During each start bootstrapper compares version file version.json in the app folder with version file on a remote server. If updates found bootstrapper detects it and installs new version of the embedded app or installs new content. Source code for the bootstrapper you could find at Git, flow diagram you can fins in the blogpost . (Note that this version still uses old cordova.file plugin conventions for device file system)
  • 29. Optimization tips 1. Only release versions of the app should be published 2. Exclude console output in release version of the app 3. AngularJS ng-repeat might significantly slow down a hybrid app. Critical case is when each ng- repeat item contain other angular bindin(s) 4. Minimize amount of angular bindings in HTML code 5. Allways manually unregister Jquery listeners at onDestroy event as angular don’t do it automatically 6. Allways manually clean all detached DOM elements at onDestroy event as angular don’t do it automatically 7. Use bind-once bindings if you don’t expect binded value to be changed (see directive template) 8. Starting from angularJS v1.3.5 It is possible to turn off angular debug data (see docs)
  • 30. Ionic/Angular issues (1) • Ionic scroll (overflow-scroll=“false”) gives problem with $ionicScrollDelegate.scrollTo() function. We solve it by using native scrolling (overflow-scroll=“true”) • Tap during scroll issue. Touching of a list item during scroll process results in firing touch event of another item. This bug could be solved by using scroll detection $ionicScrollDelegate.on- scroll or by creating a directive in case of overflow-scroll=“false”: angular.module('directive.scrolldetector', []) .directive('scrollDetector', function ($window) { return { restrict: 'A', link: function (scope, element, attrs) { function handler(e) { scope.$evalAsync(function () { scope.$eval((<any>attrs).scrollDetector); }); } scope.$on('$destroy', () => { element[0].removeEventListener("scroll", handler); }); element[0].addEventListener("scroll", handler); } } }); Next create function that we can call to check if scrolling is active: $rootScope.onScroll = () => { $rootScope.lastScrollTimestamp = (new Date()).getTime(); } $rootScope.isScrolling = () => { //to be sure that at least 300 ms we have no scrolling if ($rootScope.lastScrollTimestamp + 300 > (new Date()).getTime()) { return true; } else { return false; }} usage: in html: <ion-content overflow-scroll="true" scroll-detector="onScroll()"> in script: onTap = (e) => { if (typeof $rootScope.isScrolling == 'function' && !$rootScope.isScrolling()) { //tap event here }}
  • 31. Ionic/Angular issues (2) • Angular digest loop and $ionicLoading sync issue. Let’s imagine that you want to use $ionicLoading mesage right before script start heavy calculation. You will probably write the following: $ionicLoading.show({ template: ‘wait…’, noBackdrop: true }); //script for heavy calc which will result in heavy calc first and only then you will see your message. Next you will probably add timeout wrapper to push your heave calc script call to digest loop right after $ionicLoading.show call: $ionicLoading.show({ template: ‘wait…’, noBackdrop: true }); $timeout(()={ //script for heavy calc }); which results with the same problem. We don’t know the clean way to solve the issue and as a workaround we use this: $ionicLoading.show({ template: ‘wait…’, noBackdrop: true }); $timeout(()={ //script for heavy calc }, 300);
  • 32. References 1. http://nodejs.org/ 2. https://angularjs.org/ 3. https://github.com/angular-ui/ui- router 4. http://ionicframework.com/ 5. http://www.typescriptlang.org/ 6. http://cordova.apache.org/ 7. http://plugins.cordova.io/#/ 8. http://www.genymotion.com/ 9. https://conemu.codeplex.com/ 10. http://www.totalcmd.net/plugring/an droid_adb.html