Expert
- Using of accelerometer
- Using additional touch events
- Memory management in hybrid application
- Battery management in hybrid application
- Crash reporting
- Features and restrictions of each platform using
- Publishing of application
Using of accelerometer
n accelerometer is an electromechanical device used to measure acceleration forces. Such forces may be static, like the continuous force of gravity or, as is the case with many mobile devices, dynamic to sense movement or vibrations.
Acceleration is the measurement of the change in velocity, or speed divided by time. For example, a car accelerating from a standstill to 60 mph in six seconds is determined to have an acceleration of 10 mph per second (60 divided by 6).
react-native-sensors provides a RxJS based interface for Accelerometer, Gyroscope, and Magnetometer. It’s API is consistent with the different sensor types and platforms.
React Native example:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View
} from 'react-native';
import { Accelerometer } from "react-native-sensors";
const Value = ({name, value}) => (
<View style={styles.valueContainer}>
<Text style={styles.valueName}>{name}:</Text>
<Text style={styles.valueValue}>{new String(value).substr(0, 8)}</Text>
</View>
)
export default class App extends Component {
constructor(props) {
super(props);
new Accelerometer({
updateInterval: 400 // defaults to 100ms
})
.then(observable => {
observable.subscribe(({x,y,z}) => this.setState({x,y,z}));
})
.catch(error => {
console.log("The sensor is not available");
});
this.state = {x: 0, y: 0, z: 0};
}
render() {
return (
<View style={styles.container}>
<Text style={styles.headline}>
Accelerometer values
</Text>
<Value name="x" value={this.state.x} />
<Value name="y" value={this.state.y} />
<Value name="z" value={this.state.z} />
</View>
);
}
}
Using additional touch events
Double tap event
On touch devices, if you want to detect a double-tap gesture, you shouldn’t use the nonstandard ondblclick event; in most cases it will not work and it will also fire an onclick. The best solution (also compatible with non-touch devices) is to implement a tap–double tap detection pattern using the following code sample:
var doubletapDeltaTime_ = 700;
var doubletap1Function_ = null;
var doubletap2Function_ = null;
var doubletapTimer = null;
function tap(singleTapFunc, doubleTapFunc) {
if (doubletapTimer==null) {
// First tap, we wait X ms to the second tap
doubletapTimer_ = setTimeout(doubletapTimeout_, doubletapDeltaTime_);
doubletap1Function_ = singleTapFunc;
doubletap2Function_ = doubleTapFunc;
} else {
// Second tap
clearTimeout(doubletapTimer);
doubletapTimer_ = null;
doubletap2Function_();
}
}
function doubletapTimeout() {
// Wait for second tap timeout
doubletap1Function_();
doubleTapTimer_ = null;
}
We can use the previous library like this:
<img src="bigbutton.png" onclick="tap(tapOnce, tapTwice)" />
Touch & multitouch events
The user can touch the screen with up to five fingers at the same time (11 fingers on the iPad) and the JavaScript code will receive the event for this. For multitouch detection, we should not use the standard onclick event. Instead, we should replace it with the following nonstandard events:
- ontouchstart
- ontouchmove
- ontouchend
- ontouchcancel
When we capture these events, we will receive them both for single touches and multitouches. Every time the user presses a finger on the screen, ontouchstart will be executed; if she moves one or more fingers, ontouchmove will be the event to capture; and when the user removes her fingers, ontouchend will be fired. What about ontouchcancel? A touch cancel event is executed if any external event with more priority than our website (e.g., an alert window, an incoming call, or a push notification) cancels the operation.
The four multitouch events receive the same event object (TouchEvent) as a parameter. It contains a touches array representing the coordinates of each touch on the page; each array element is an object with pageX and pageY properties. If the device is not multitouch- enabled, you will receive an array of only one element.
<div
ontouchstart="touchStart(event);"
ontouchmove="touchMove(event);"
ontouchend="touchEnd(event);"
ontouchcancel="touchCancel(event);">
</div>
The TouchEvent object supports the array collections:
| TouchEvent attribute | Description |
|---|---|
| touches | All the touches actually on the screen |
| targetTouches | Only the touches inside the target element of the event |
| changedTouches | Only the touches that changed since the last event call (useful in ontouchmove and ontouchend or to filter only new or removed touches) |
Every Touch object has the properties outlined in table:
| Touch attribute | Description |
|---|---|
| clientX, clientY | Touch coordinates relative to the viewport |
| screenX, screenY | Touch coordinates relative to the screen |
| pageX, pageY | Touch coordinates relative to the whole page, including the scroll position |
| identifier | A number for identifying the touch between event calls |
| target | The original HTML element where the event was originated |
Key events
Key events—onkeypress, onkeyup, and onkeydown—allow us to detect keypresses over the whole page (body) or in one element (generally, a text input). On compatible mobile devices, this can be useful for many situations:
- To provide keyboard shortcuts
- To provide navigation or movement in a game or application
- To enable form submission on Enter or another keypress
- To disallow some characters in a text input
If we are going to prevent a key from being used, we should be very careful. Remember that devices can have very different keyboards. Some devices have only virtual keyboards, some numeric, and some QWERTY, and key code management across platforms can be a little tricky.
Touch Gestures
A gesture is a way of combining finger movements over the screen to fire an action, instead of using a simple touch or click. A complete touch (or mouse) move-capturing feature is required in order for gestures to be registered, and to be perfectly honest, today only mobile Safari and the Android browser offer good support.
Swipe gesture
The swipe (also known as flip) gesture is a touch-based browser technique typically used for going forward and backward. For example, it is used in many photo galleries to change the currently displayed image, and in presentations to move from slide to slide. The gesture is simply a finger moving across the x-axis from left to right or right to left (a horizontal swipe) or along the y-axis from top to bottom or bottom to top (a vertical swipe). It is a one-finger gesture, so it is compatible with almost any touch device.
There is no standard event that captures the swipe action, so we need to emulate it using standard events.
The steps will be:
- Capture onmousedown (or ontouchstart for iPhone and compatible browsers) and start a gesture recording.
- Capture onmousemove (or ontouchmove for iPhone and compatible browsers) and continue the gesture recording if the move is on the x-axis (or y-axis), within a certain threshold. Cancel the gesture if the move is on the other axis.
- Capture onmouseup (or ontouchend for iPhone and compatible browsers) and, if the gesture was active and the difference between the original and final coordinates is greater than a predefined constant, define a swipe to one direction.
The last item can be replaced with an on-the-fly verification of the gesture inside the onmousemove event.
Zoom and rotate gestures
One of the coolest features of the iPhone when it was presented as a new phone was the zoom and rotate gesture. Using a pinching gesture with two fingers, the user can zoom in and zoom out on content (generally a picture), and using two fingers moving in a circle, he can rotate that picture.
Events available for touch handling:
| Event | Description |
|---|---|
| ongesturestart | Fired when the user starts a gesture using two fingers |
| ongesturechange | Fired when the user is moving her fingers, rotating or pinching |
| ongestureend | Fired when the user lifts one or both fingers |
The same events are used for rotate and zoom gestures. All three events receive a GestureEvent parameter. This parameter has typical event properties, and the additional properties scale and rotation.
The scale property defines the distance between the two fingers as a floating-point multiplier of the initial distance when the gesture started. If this value is greater than 1.0 it is a pinch open (zoom in), and if it is lower than 1.0 it is a pinch close (zoom out).
The rotation value gives the delta rotation from the initial point, in degrees. If the user is rotating clockwise we will get a positive
Memory management in hybrid application
In React Native world each JS module scope is attached to a root object. Many modules, including React Native core ones, declare variables that are kept in the main scope (e.g., when you define an object outside of a class or function in your JS module). Such variables may retain other objects and hence prevent them from being garbage collected. Here is a list of most common mistakes in React Native apps that can lead to memory leaks:
- Unreleased timers/listeners added in componentDidMount This is a no. 1 reason for memory leaks in React apps in general. Let’s look at the following component that listens to keyboard showing and hiding events:
class Composer extends Component {
state = { showAccessory: false }
componentDidMount() {
Keyboard.addListener('keyboardDidShow', () => this.setState({ showAccessory: true }));
Keyboard.addListener('keyboardDidHide', () => this.setState({ showAccessory: false }));
}
render() {
return (
<View>
<EditTextComponent />
{this.state.showAccessory && <AccessoryView />}
</View>
);
}
}
Since we never remove these listeners, they will still receive keyboard events even after component gets unmounted. At the same time, Keyboard module has to keep the list of active listeners in global scope — in our case, it will retain the arrow functions we pass to addListener method. In turn, these arrow functions retain this – i.e., the reference to the Composer component, which in turn references its properties via this.props, its children via this.props.children, its children’s children, etc. This simple mistake can lead to very large areas of memory left retained by accident.
- Closure scope leaks
Closure scope leaks are much more difficult to avoid — but not necessarily harder to track down.
A closure scope is an object containing all the variables outside of closure that are being referenced from within that closure.
Let’s imagine we want to build a countdown timer component. It takes initial time as props and keeps the current time that is left in its state. To update the timer, we will use setInterval in componentDidMount:
componentDidMount() {
let { countdown, hours, mins, sec } = this.props;
if (countdown) {
this._interval = setInterval(() => {
sec -= 1;
if (sec < 0) {
sec = 59;
mins -= 1;
}
if (mins < 0) {
mins = 59;
hours -= 1;
}
if (hours < 0) {
clearInterval(this._interval);
} else {
this.setState({ hours, mins, sec });
}
}, 1000);
}
}
WARNING
As our experience shows, lifecycle methods that accept previous state or props (i.e., componentDidUpdate or getDerivedStateFromProps) are the most common source of memory leaks via closure scope in React apps.
The easiest way to observe that is by using Instruments on iOS or Android Studio Profiler tab for Android. Both of those tools show the total memory usage of the app — this includes both memory allocated by JS, as well as the memory allocated by native modules and views. Let’s take a look how to use them:
Battery management in hybrid application
PhoneGap/Apache Cordova Lifecycle Events
batterystatus & batterycritical
If you have power concerns, or simply want to be aware of when the battery status changes (i.e. - charge drops, or the device is plugged in, etc.), you can use the batterystatus event, which provides an event callback argument with level (charge percentage) and an isPlugged flag to indicate if the device is plugged in. (Unfortunately the level property doesn't work on Windows Phone devices.)
document.addEventListener("batterystatus", function(info) {
if(!info.isPlugged) {
app.message("The battery level is currently " + info.level + ".");
}
});
You can also use the batterycritical event – it's emitted when the battery reaches a critical threshold (which is device specific). It also provides the level and isPlugged data on the callback argument:
document.addEventListener("batterycritical", function(info) {
if(!info.isPlugged) {
app.message("The battery level is critically low (" + info.level + ")! Time to plug this puppy in!");
}
});
React Native
react-native-battery:
const React = require('react-native');
const BatteryManager = require('NativeModules').BatteryManager;
const {
AppRegistry,
StyleSheet,
Text,
View,
DeviceEventEmitter,
} = React;
const RCTBattery = React.createClass({
getInitialState: function() {
return {batteryLevel: null, charging:false};
},
onBatteryStatus: function(info){
this.setState({batteryLevel: info.level});
this.setState({charging: info.isPlugged});
},
componentDidMount: function(){
BatteryManager.updateBatteryLevel(function(info){
this._subscription = DeviceEventEmitter.addListener('BatteryStatus', this.onBatteryStatus);
this.setState({batteryLevel: info.level});
this.setState({charging: info.isPlugged});
}.bind(this));
},
componentWillUnmount: function(){
this._subscription.remove();
},
render: function() {
var chargingText;
if(this.state.charging){
chargingText =<Text style={styles.instructions}>Charging </Text>;
} else {
chargingText =<Text style={styles.instructions}>Not Charging </Text>;
}
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Battery Level {this.state.batteryLevel}
</Text>
{chargingText}
</View>
);
}
});
Crash reporting
One of the platforms we’ve been most excited about over the last couple of years is React Native. Since Bugsnag for React Native launched in October 2016, we’ve added support for App Center CodePush and automatic breadcrumbs, and released the stability score. In collaboration with the engineering team at Airbnb, we were able to identify common problems when detecting crashes and reports in React Native. All this work has led many teams, like Zynga and the popular game Words With Friends, to adopt Bugsnag for “best in class support for React Native and sourcemaps.”
Bugsnag for React Native allows you to automatically detect crashes in your React Native applications and gives you a stability score for every release. This metric can help you decide if you should be building new features or fixing bugs that impact your users.
Detect crashes in your React Native apps
One of the tricky problems with React Native crash reporting is identifying the source of the crash (is it in your JavaScript or native code?) and properly applying mapping files in order to reveal a readable stacktrace.
Bugsnag for React Native detects crashes across the JavaScript and native platform layers (iOS and Android), and reports those errors in a single project. We support source maps for the JavaScript layer, dSYMs for iOS, and ProGuard mapping files for Android so you receive a fully de-minified/de-obfuscated stacktrace for every crash, regardless of where it originates in your code.
React Native + App Center CodePush
Since the time of our launch, App Center CodePush emerged as a popular tool for deploying updates directly to users of React Native applications. There are some limitations as you can only update your JavaScript bundle, but it’s a powerful tool for deploying hot fixes and enhancements quickly to your users.
Bugsnag supports App Center CodePush so you can make use of this tool alongside your crash reporting. That way you can monitor CodePush releases with Bugsnag and make sure you haven’t accidentally introduced any new bugs through your JavaScript updates.
Stability score for your React Native releases Understanding application stability is key for all software teams, but especially for teams deploying React Native applications where there are many variables at play. Every time you make a release, Bugsnag assigns a stability score out of 100% to let you know if you are hitting your targets for stability, or if you’ve introduced bugs into your application.
React Native crash reports
Automatically captured React Native data Along with a full stacktrace, Bugsnag for React Native also automatically collects important diagnostic information about the crash. Here’s a list of all the data Bugsnag will capture automatically:
- Stacktrace
- Battery state
- Device model + OS version
- Thread state
- App running duration in foreground or background
- Device + vendor specific identifier
———
Installing Bugsnag for React Native has been optimized to be as easy as possible, and includes an installation script that automatically sets up the native portions of your application.
If you’re new to Bugsnag, you can try it out with our 14-day free trial.
Features and restrictions of each platform using
Overall Findings
| Native Apps | Web Apps |
|---|---|
| Works for a certain mobile device. | App is internet-enabled. |
| App is downloaded onto a mobile device. | Users access the app from their mobile device's web browser. |
| Functionality integrated with device's features. | Easy to maintain due to common code base across multiple mobile platforms. |
| Often perform faster than web apps. | Can be made compatible with any older mobile device. |
| App store approval process guarantees security and compatibility. | Can be released at developer's discretion since there's no app store approval process. |
| Developers provided with SDK and other tools for ease of development. | Limited in what device features it can access. |
| Can be more expensive to create and maintain. | Safety and security not guaranteed. |
| App store approval process can be daunting. | More opportunities to monetize. |
Native apps and web apps are both useful tools for users and worthwhile endeavors for developers. A native app works with a device's built-in features and is downloaded from an app marketplace, while web apps are accessed via the internet.
From a user's perspective, native and web apps can look and work very much the same. A developer may want to focus on native apps if they are interested in creating a user-centric tool. They may wish to focus on creating a web app if their app's functionality is application-specific. Many developers create both native and web apps to widen the reach of their products and offer the best possible user experience.
Native Apps and Web Apps: Basic Differences
| Native Apps | Web Apps |
|---|---|
| Developed for one particular mobile device. | Internet-enabled app. |
| Installed directly on device. | Accessible via mobile device's web browser. |
| Downloaded from an app store or marketplace. | Don't need to be downloaded. |
| Uses device's native features. | Limited in what native features it can use. |
Native apps and web apps have some basic structural and developmental differences.
A native app is developed for a particular mobile device. It's installed directly onto the device itself. A native app is totally compatible with a device’s hardware and native features, such as an accelerometer, camera, and more, so a developer can incorporate these features into an app. Users download native apps from an app store or online marketplace such as Apple's App Store or Google's Google Play Store.
A web app is an internet-enabled app that is accessible via the mobile device’s web browser. Users don't have to download a web app onto their mobile device. Web apps can access only a limited amount of a device’s native features.
User's Perspective: Both Have Strengths and Drawbacks
| Native Apps | Web Apps |
|---|---|
| Work with device's built-in features. | Users don't see any interface differences. |
| Perform faster on the device. | Users don't have to go to an app store to download. |
| Easier to work with. | Users don't have to worry if the app needs an update. |
| Users don't have to worry about security. | Not as much support across various mobile browsers. |
| Users don't have to worry about device compatibility. | Users may be more worried about security since there's no standardized quality control. |
| Due to various versions, users may have trouble communicating with other users of the app (e.g., games). |
Developers want users to like their apps and find them helpful and easy to use. For the most part, both native apps and web apps are easy for users to access and work with. Still, each has its pros and cons as far as what a user may prefer.
Native apps are easy to download and work with. They're usually inexpensive and may offer a free or "lite" version. There's no need to worry about device compatibility or security because these apps have been fully vetted by the app store or marketplace. Native apps are faster and more efficient, as they work in tandem with the mobile device for which they've been developed. Native apps do require updating, however, so users must pay attention to make sure they have the latest version of an app. If users are playing a game with another user with a different app version, there can be some communication issues.
For users, web apps don't appear to be very different from native apps as far as interface and operation. Since web apps are accessed via a browser, there's no need for a user to find the app and download it onto their mobile device. There's no need to worry if the app needs an update since the latest version is always accessible. On the downside, users may be wary of security issues since web apps aren't subject to standardized quality control.
Developer's Perspective: Pros and Cons for Each
| Native Apps | Web Apps |
|---|---|
| Mobile platforms have unique development processes. | Various mobile devices and browsers present unique challenges. |
| Different programming languages needed for various platforms. | Don't need approval from any app marketplace. |
| More expensive to develop. | No standardized SDKs or easy tools. |
| Monetization is tricky, but app stores handle payments. | Easier to monetize apps with ads, memberships, etc. |
| Getting approved can be difficult. |
The app development process for native apps and web apps is different. Some aspects of each are easier for developers, but each also has its drawbacks.
NATIVE APPS
Native apps are generally more expensive to develop. Developers have to pay attention to the mobile platforms they're working with because each platform has its own unique development process. Mobile platforms use various native programming languages, for example, iOS uses Objective-C, Android uses Java, Windows Mobile uses C++, etc. On the plus side, each mobile platform has its own standardized software development kit (SDK), development tools, and other user-interface elements, so developers can create their native apps with relative ease.
App monetization with native apps can be tricky, since mobile device manufacturers may lay restrictions on integrating services with mobile ad platforms and networks. Still, once your app is set up, the app store takes care of your revenue and commissions, which is nice.
Because app stores vet native apps so thoroughly, the process of getting a native app approved on an app store can be long and tedious for the developer. Sometimes apps are rejected and the developer has to make extensive changes.
WEB APPS
Unlike native apps, developers don't have to submit web apps to any app store for approval. Since web apps don't need to be approved by an app marketplace, they can be released at any time and in any form the developer prefers.
Web app developers have to deal with the unique features and problems that come with various mobile devices and browsers. Web app developers use languages such as JavaScript, HTML 5, CSS3, or other web application frameworks. There are no standardized SDKs for web developers. There are, however, several tools and frameworks to help web app developers deploy their apps to multiple mobile platforms and browsers.
It's easy to monetize your web apps via advertisements, membership fees, etc. However, you need to set up your own payment system. Web apps are much easier to maintain because they have a common code base across multiple mobile platforms. However, maintaining apps across multiple platforms presents its own challenges.
While you don't have to jump through hoops to get an app approved, there is no specific regulatory authority to control the quality standards of these apps. Without a specific marketplace or store, it's harder to make your app visible to potential users.
Final Verdict
When deciding between developing native apps or web apps, consider how important your app's speed and performance is to you, if you want your app to include any device-specific features, and if you prefer your app to be internet-enabled. Your development budget is a factor, as is how you'd like to monetize your app in the future and what mobile platforms you want to support.
Many developers opt to work with both types of apps to widen the reach of their products and offer the best possible user experience.
Publishing of application
- Play Market
- AppleStore
- Windows Store
publish to Play Market & App store video
Deploying React Native Apps to App Store and Play Market : Step-by-Step Guide