Chapter 3. Getting Started with Mobile Applications

In Chapter 2, Building and Debugging on Multiple Platforms, you learned how to configure your development environment, emulate a mobile application, and choose the most useful tools to debug it. In this chapter you will learn how to improve the performance of a mobile app. You will see how to define the building blocks of a modern hybrid app built using web standards and PhoneGap.

In this chapter you will:

  • Review some basic knowledge of mobile web development
  • Explore best practices to write quality code for your app
  • Review some best practices for performance optimization
  • Get an overview of the most popular app frameworks
  • Learn how to create a project folder structure optimized for cross-platform development with PhoneGap
  • Create a "Hello World" app using a framework
  • Learn how to add a native look and feel to your app

Mobile-centric HTML/CSS/JavaScript

When using PhoneGap, you create hybrid apps based upon standards. The app is rendered to the user through a WebView, which means it is a browser instance wrapped into the app itself.

For this reason, it's important to know how to use mobile-specific HTML tags, CSS properties, and JavaScript methods, properties, and events.

The viewport meta tag

The viewport meta tag was introduced by Apple with iOS 1.0 and is largely supported in all the major mobile browsers. When a web page doesn't fit the size of the browser, the default behavior of a mobile browser is to scale it. The viewport meta tag is what you need in order to have control over this behavior.

A viewport meta tag looks like the following code snippet:

<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, minimum-scale=1, maximum-scale=1.5, user-scalable=1">

What you are actually saying to the browser is that the default width and height of the content are the width and height of the device screen (width=device-width and height=device-height), that the content is scalable (user-scalable=1), and what the minimum and maximum scale is (minimum-scale=1 and maximum-scale=1.5).

An exhaustive reference about the viewport meta tag is available on the Apple Developer Library website at https://developer.apple.com/library/safari/#documentation/appleapplications/reference/SafariHTMLRef/Articles/MetaTags.html. Some useful information is available on the Opera developers website at http://dev.opera.com/articles/view/an-introduction-to-meta-viewport-and-viewport/.

Remember that by default the WebView used by PhoneGap ignores the settings defined in the viewport meta tag; you will learn during this chapter how to enable the handling of the viewport settings in your app.

Unwanted telephone number linking

Mobile browser click-to-call format detection on most phones isn't that accurate; plenty of numbers get selected, including addresses, ISBN numbers, and a variety of different types of numeric data that aren't phone numbers. In order to avoid any possible issues and to have full control on a call from your HTML markup, it is necessary to add the following meta tag to the header of your page:

<meta name="format-detection" content="telephone=no">

Defining this tag you can then control how to handle numbers using the tel or the sms scheme in the href attribute:

<a href="tel:18005555555">Call us at 1-800-555-5555</a>
<a href="sms:18005555555?body=Text%20goes%20here">

Autocorrect

Submitting data using mobile devices is a tedious operation for the user, because sometimes the built-in autocorrect features don't help at all. In order to disable the autocorrect features, use the autocorrect, autocomplete, and autocapitalize attributes in conjunction with an input field:

  <input autocorrect="off" autocomplete="off" autocapitalize="off">

CSS media queries and mobile properties

One of the interesting features of CSS is media queries. Media queries themselves are actually quite old and are not mobile-specific, but they are really useful when handling different screen sizes on mobiles. Media queries can be used inline:

@media all and (orientation: portrait) {  
    body { }  
    div { }  
}

Or as the media attribute of a link tag:

<link rel="stylesheet" media="all and (orientation: portrait)" href="portrait.css" />

There is no best way to use them because it depends on the type of app. Using media queries inline, the CSS file tends to grow and the parsing can be slow on old devices. On the other hand, having CSS rules organized in separate files helps to keep the code well organized and speeds up the parsing, but it means more HTTP calls that are usually not the best option on mobiles due to the latency of mobile connections.

A good balance should be reached using offline caching strategies, which you will learn more about in the next chapters.

There are several CSS mobile-specific properties; most of them are vendor-specific and are identified with prefixes. The most common properties used in mobile development are:

  • -webkit-tap-highlight-color (iOS): This overrides the semitransparent color overlay when a user clicks on a link or clickable element, this the only property which is iOS specific
  • -webkit-user-select: This prevents the user from selecting text
  • -webkit-touch-callout: This prevents the callout toolbar from appearing when a user touches and holds an element such as an anchor tag

Always remember that the usage of browser prefixes in JavaScript is possible only using mixed case or lower camel case formatting, which means that in order to prevent the user from selecting text through JavaScript you have to use the following syntax:

yourElementVariable.style.webkitUserSelect = 'none';

The camel case formatting is due to the fact that the dash sign cannot be used in a variable name in JavaScript.

JavaScript for mobile 101

With JavaScript, you can add interactivity to an app and define its behavior. The JavaScript community is really vibrant and there are thousands of frameworks and utilities around the web you can use to speed up development or enhance the user experience.

Note

In this book, I will briefly cover relevant JavaScript syntax where necessary. However, if you need to consult a reference guide for JavaScript, check out David Flanagan's JavaScript: The Definitive Guide or visit the Mozilla Developer Network at http://developer.mozilla.org or the Apple Safari Developer Library at http://developer.apple.com/library/safari.

One of the most common questions among new developers is whether it's a good habit to use external frameworks. One school of developers strongly opposes the use of external frameworks, because they add weight to an app. In my opinion it depends on the nature of the app. This doesn't mean that a complex app needs a framework and a simple one doesn't; instead, it depends on the architecture and on the features of your app.

I use jQuery and I love it, but I will not advise the use of jQuery when building a hybrid multi-page app. Also, if the jQuery library is downloaded once, the file is parsed each time it's included in an HTML page. Performance on mobiles is crucial. If you don't seriously consider optimizing each aspect of your app, you risk losing users. Bad performance can also lead to high battery consumption.

There aren't too many tools to analyze performance on the market right now, so you have to rely on the ones you have in your browser. You can test your pages using several resources such as http://gtmetrix.com/, http://blazemeter.com/, and http://mobitest.akamai.com/.

Let's review the basics of adding interactivity without using jQuery and some mobile-specific JavaScript APIs.

querySelector and querySelectorAll

The getElementById() method accesses the first element with the specified ID. It's one of the oldest and most well-known methods of the document object; these days, however, it is often replaced by jQuery selectors that are usually more accurate and provide better cross-browser support.

There are also other methods to inspect the DOM, including querySelector and querySelectorAll . querySelectorAll is a new DOM API that accepts CSS classes, IDs, or HTML tags and returns the element(s) it matches.

// Recover the first <p> tags in the current document
var first = document.querySelector ('p'),

// Recover all the <p> tags in the current document
var all = document.querySelectorAll('p'),

addEventListener

One of the means we have to ensure unobtrusive JavaScript is the addEventListener function, the DOM level 2 mechanism to register event listeners.

Using addEventListener you can get a better separation of concerns, define multiple listeners, and handle custom events efficiently as you will do in the "Hello World" sample app that will listen for the device to be ready before enabling its controls. It's good practice to separate application logic from the event handlers in order to keep the code cleaner and to make it easier writing tests.

addEventListener('event', eventHandler);

function eventHandler(evt){
    
    // Call another function and eventually pass the 
    // values stored in the event object 

}

Don't pass the event object around but just the values needed by the function you are calling.

Screen orientation

The screen orientation is important when dealing with an app because the size of the screen dramatically changes when the orientation is changed. The orientationchange event is triggered at every 90 degrees of rotation (portrait and landscape modes), and it's possible to listen to it using addEventListener; the current orientation is available through window.orientation.

Device orientation

If you want to get more detailed information about the orientation of the device, you can define a listener for the deviceorientation event. The deviceorientation event will fire very frequently and gives information about the device's orientation in three dimensions.

The deviceorientation event is strictly related to the existence on the device of a gyroscope; the gyroscope measures the 3D angle orientation, even when the device is at rest.

Shake gestures

Gesture handling is the key for successful apps. The devicemotion event fires when the user shakes or moves his/her device. The devicemotion event is strictly related to the accelerometer, which fires events off when the device accelerates.

Media capture API

While old versions of iOS are still lacking basic file input, Android, iOS Version 6 and later, Windows Phone 8 and BlackBerry 10 are giving developers fine-grained control over content users can upload and allow you to access the device camera and microphone.

<!-- opens directly to the camera --><input type="file" accept="image/*;capture=camera"></input>
<!-- opens directly to the camera in video mode --><input type="file" accept="video/*;capture=camcorder"></input>
<!-- opens directly to the audio recorder -->  <input type="file" accept="audio/*;capture=microphone"></input>

Data URI

You can represent an image as a Base64 string, which ensures higher performance because there is no TCP negotiation in order to open a new HTTP connection. Practically speaking it means that there is a lower latency when compared to the usual way to load an image on the Web. When a base64 string is assigned as the src attribute to an img tag the code looks like the following snippet:

<img src='data:image/png;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub// ge8WSLf/rhf/3kdbW1mxsbP//mf/// yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0 ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFj sVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/ gAwXEQA7' width='16' height='14' >

When converting an image to Base64 there is a 30-40 percent weight increase; for this reason, you have to optimize the image carefully before converting it and when possible activate gzip compression on the server.

Tip

Also, if JPEG and PNG formats are already compressed and gzip cannot compress them any further, you can use the Base64OutputStream Apache codec available at http://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/binary/Base64OutputStream.html in order to apply additional compression to the Base64 string.

Rendering a Base64 image can be very CPU-expensive for a mobile device. Consider carefully if you really need a Base64 image for your app.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.59.187