First-Class Citizen on Your Device Now
Maxim Salnikov
@webmaxru
The Mobile Web 2.0
We need a mobile app
You: ???
Maxim Salnikov
Google Developer Expert in Angular
Mobile Oslo / Angular Oslo / PWA Oslo meetups organizer
Mobile Era conference organizer
Products from the future
UI Engineer at ForgeRock
MobileEra.Rocks
-
All kinds of native mobile development
-
Progressive Web Apps
-
Mobile Web: React Native, NativeScript, Ionic
20% off with code
October 5-6, Oslo
Mobile Users
2014
October, 2016
> 2 000 000 000
60X Poland
Mobile Web
Milestones of the Mobile Web
Hybrid
Web
RWD
Native
?
The biggest mistake we’ve made as a company is betting on HTML5 over native.
Mark Zuckerberg
?
Mobile Web 2.0
Developer Experience
User Experience
Business Experience
How the things work
Ionic
One code base. Running everywhere.
-
Single code base for app stores and web
-
Web app in WebView
-
Powered by Angular
-
Built to native app with Cordova
-
Uses platform APIs via Cordova
Ionic
Open source framework for building truly native mobile apps
NativeScript
NativeScript
-
Uses Angular (not a requirement)
-
Uses JavaScript virtual machines to execute JavaScript commands
-
Direct access to native platform APIs
NativeScript
React Native
Learn once, write anywhere
React Native
-
Uses "bridge" between JavaScript and native
-
Inspired by React (Virtual DOM, etc)
-
Can be a part of native app
-
Can include modules with native code
React Native
Progressive Web Apps
Reliable, Fast, Engaging
Progressive Web Apps
-
Takes the best parts from native and web
-
Framework-agnostic
-
Use the latest browser APIs
Progressive Web Apps
Developer Experience
Installation, set up, scaffolding
-
Smooth NPM-based installation
-
CLI-based scaffolding
-
Tools to preview/emulate the app
-
Tools to share and deploy
Coding and UI
Angular
TypeScript
"HTML"
Ionic
<ion-header>
<ion-navbar>
<ion-title>Ionic Blank</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding class="content">
<h2>Tap the button</h2>
<button primary>TAP</button>
<div class="message">16 taps left</div>
</ion-content>
Ionic
Writing a code
Angular
TypeScript
"HTML"
Angular?
TypeScript
or
Javascript
XML
NativeScript
<ActionBar title="NativeScript Blank"></ActionBar>
<StackLayout>
<Label text="Tap the button" class="title"></Label>
<Button text="TAP"></Button>
<Label [text]="message" class="message"></Label>
</StackLayout>
NativeScript
Writing a code
Angular
TypeScript
"HTML"
Angular?
TypeScript
or
Javascript
XML
React
ES6
JSX
React Native
import React, { Component } from 'react';
import { View, Button, Alert, AppRegistry } from 'react-native';
class MainApp extends Component {
_onPress() {
Alert.alert('I am so pressed!');
}
render() {
return (
<View>
<Button onPress={this._onPress} title="Press me" color="#841584" />
</View>
);
}
}
AppRegistry.registerComponent('MainApp', () => MainApp);
React Native
Action Bar / iOS
import React, { Component, PropTypes } from 'react';
import { NavigatorIOS, Text } from 'react-native';
export default class NavigatorIOSApp extends Component {
render() {
return (
<NavigatorIOS
initialRoute={{
component: MyScene,
title: 'My Initial Scene',
}}
style={{flex: 1}}
/>
);
}
}
Action Bar / Android
render: function() {
return (
<ToolbarAndroid
logo={require('./app_logo.png')}
title="AwesomeApp"
actions={[{title: 'Settings', icon: require('./icon.png')}]}
onActionSelected={this.onActionSelected} />
)
},
onActionSelected: function(position) {
if (position === 0) { // index of 'Settings'
showSettings();
}
}
Should be noted
-
There are iOS/Android specific limitations of ActionBar in NativeScript
-
There are cross-platform implementations of navigation in React Native (React Native Navigation)
Writing a code
Angular
TypeScript
"HTML"
Angular?
TypeScript
or
Javascript
XML
React
ES6
JSX
Any framework
Whatever
transpiled to
Javascript
HTML
Progressive Web Apps
...a new framework of the week
Hacker News PWA
-
A spiritual successor to TodoMVC
-
8 implementations at the moment
Progressive Web Apps
Accessing hardware
Ionic
Native
Ionic Native
$ ionic cordova plugin add cordova-plugin-camera
$ npm install --save @ionic-native/camera
Ionic Native
import { Camera, CameraOptions } from '@ionic-native/camera';
constructor(private camera: Camera) { }
...
const options: CameraOptions = {
quality: 100,
...
}
this.camera.getPicture(options).then((imageData) => {
// imageData is either a base64 encoded string or a file URI
// If it's base64:
let base64Image = 'data:image/jpeg;base64,' + imageData;
}, (err) => {
// Handle error
});
Accessing hardware
Ionic
Native
Direct access to native APIs
CocoaPods
Plugins
NativeScript
$ npm install nativescript-camera --save
NativeScript
import { Component } from "@angular/core";
import { ImageAsset } from "image-asset";
import { takePicture, requestPermissions, isAvailable } from "nativescript-camera";
@Component({
moduleId: module.id,
templateUrl: "./using-camera.component.html"
})
export class UsingCameraExampleComponent {
public imageTaken: ImageAsset;
onTakePhoto() {
let options = {
width: 600,
height: 300,
...
};
takePicture(options)
.then(imageAsset => {
this.imageTaken = imageAsset;
console.log("Size: " + imageAsset.options.width + "x" + imageAsset.options.height);
}).catch(err => {
console.log(err.message);
});
}
}
Accessing hardware
Ionic
Native
Direct access to native APIs
CocoaPods
Plugins
APIs
Writing native code
Components
React Native
$ npm install react-native-camera --save
$ react-native link react-native-camera
React Native
import React, { Component } from 'react';
...
import Camera from 'react-native-camera';
class BadInstagramCloneApp extends Component {
render() {
return (
<View>
<Camera
ref={(cam) => {
this.camera = cam;
}}
aspect={Camera.constants.Aspect.fill}>
<Text onPress={this.takePicture.bind(this)}>[CAPTURE]</Text>
</Camera>
</View>
);
}
takePicture() {
const options = {};
//options.location = ...
this.camera.capture({metadata: options})
.then((data) => console.log(data))
.catch(err => console.error(err));
}
}
AppRegistry.registerComponent('BadInstagramCloneApp', () => BadInstagramCloneApp);
Accessing hardware
Ionic
Native
Direct access to native APIs
CocoaPods
Plugins
APIs
Writing native code
Components
Web APIs
What Web Can Do
User Experience
Performance
-
No serious performance difference between the native and NativeScript/React Native
-
A hybrid version of an app will never be as fast as a native version
Performance
-
Performance doesn’t matter so much as long as the hybrid app is fast enough
-
Javascript on Chrome for Android became 35% faster during the last year
Business Experience
-
48% of consumers start mobile research with a search engine
-
NativeScript and React Native apps could only be distributed via app stores
-
Ionic goes smart cross-platform approach
Discoverability
-
60% of apps in the Google Play app store have never been downloaded
-
The average user downloads <3 apps per month
-
50% of US smartphone users download 0 apps per month
-
Very expensive to acquire users for mobile apps
App stores...
-
Easy to find
-
Easy to share
-
Easy to install
-
Easy to update
PWA wins!
We need a mobile app
You: !!!
> 50%
> 1 000 000 000
Dziękuję Ci bardzo
@webmaxru
Maxim Salnikov
Questions?
The Mobile Web Second Edition: First-Class Citizen on Your Device Now
By Maxim Salnikov
The Mobile Web Second Edition: First-Class Citizen on Your Device Now
They are so similar: Web and Mobile apps. What a nice option to use our web development experience (JavaScript, to be specific) to create cross-platform native-like applications. Is it that simple? What are the pros and cons of mobile web VS native? What is the difference between hybrid mobile apps, progressive web apps and JavaScript-compiled-to-native ones? Let's find the answers together! Attendees will get an overview of modern concepts for building web-based mobile applications, pros and cons from tech and business sides. Bonus: some practical advices on when to go for this option. For the each option I'll give advantages/disadvantages from both tech and business points of view so both developers and managers will get a big picture of today's (and tomorrow's) possibilities of the mentioned concept.
- 3,267