Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Challenges and solutions - Architecture of a Modern Web Application - Mobile App - Part 3

4.98/5 (31 votes)
23 Oct 2013CPOL22 min read 118.6K  
Mobile app development for iOS, Android, Windows Phone, and BlackBerry.

Article Series

Introduction

In this article we will learn to write mobile apps using native, hybrid, and responsive development techniques for popular device platforms like iOS and Windows Phone for now, and later Android and BlackBerry. 

While the this article covers only the front end development for mobile app, but I would strongly recommend to evalute DreamFactory for backend REST API creation in minutes! DreamFactory is dramatically changing the landscape of how we develop and manage back-end REST APIs. This breakthrough technology could reduce time and cost of mobile app to unexpected levels.

Image 1

Figure - iOS, Android, BlackBerry, and Windows Phone

iOS Native App

Image 2

Figure - iOS 7 on iPhone5S

iOS is a mobile operating system installed on iPhone, iPod Touch, iPad, and iPad Mini. Objective-C is used to write mobile apps for these devices using Cocoa Touch API and XCode. Cocoa is used for gesture recognition, animation etc., while XCode is an integrated development environment for iOS development.

To test the app on a physical device or to publish it on App Store, an yearly $99 fee is required. To better read app code, let's take a look at Objective-C, which is very similar to C++.

Image 3

Figure - iOS7 Home Screen

Objective-C

You write iOS apps using Objective-C, a superset of C that uses SmallTalk OOP syntax. It was developed almost 33 years ago (in 1980). Let's get a hold of Objective-C first.

Image 4

Figure - Objective-C class header

To create a class in Objective-C, we add two files: header and method file:

Objective-C
// header file Button.h to declare class
@interface Button {
}
@end
Objective-C
// method file Button.m to implement class
@implementation Button

@end

Now we will add class assets, i.e., members and methods. To add a private member:

Objective-C
// way # 1 - Button.h
@interface Button {
	@private
	BOOL visible;
}
@end
Objective-C
// way # 2 - Button.m
@implementation Button
	BOOL visible;
@end

Note the parenthses right after Button, which is a way to declare a Class Extension.

Objective-C
// way # 3 - Button.m
@interface Button() { // Objective-C 2 Class Extension
	BOOL visible;
}
@end

@implementation Button
	
@end

To add a protected member (by default, class members are protected):

Objective-C
// way # 1 - Button.h
@interface Button {
	bool rounded;
}
@end
Objective-C
// way # 2 - Button.h
@interface Button {
	@protected
	bool rounded;
}
@end

To add a public member:

Objective-C
// way # 1 - Button.h
@interface Button {
	@public
	NSString* text;
}
@end

To add a public property:

Objective-C
// way # 1 - Button.h
@interface Button {
}
@property NSString* text; // an instance member _text, getter 'text'
// and setter 'setText' will be auto created
@end
Objective-C
// way # 2 - Button.h
@interface Button {
}
@property (readwrite) NSString* text; // note readwrite is default, so no need to specify
@end
Objective-C
// way # 3 - Button.h
@interface Button {
}
@property (readonly) NSString* text; // can only be get
@end
Objective-C
// way # 4 - Button.h
@interface Button {
}
@property (readonly, getter=caption) NSString* text; // override default method name 'text'
@end
Objective-C
// way # 5 - Button.h
@interface Button {
	NSString* buttonText; // instance variable
}
@property NSString* text; // to avoid creation of an instance member '_text' and use 'buttonText'
@end

// Button.m
@implementation Button

@synthesize text = buttonText; // now text will be backed by variable 'buttonText'

@end
Objective-C
// way # 6 - Button.h
@interface Button {

}
@property NSString* text; // to avoid creation of an instance member '_text'
@end

// Button.m
@implementation Button

@synthesize text; // now text will be backed by auto generated variable 'text'

@end
Objective-C
// way # 7 - Button.h
@interface Button {
}
@property (readwrite, nonatomic) NSString* text; // multiple threads can get & set text. by default atomic
@end
Objective-C
// way # 8 - Button.h
@interface Button {
}
@property (readwrite, copy) NSString* text; // 'text' will have its own copy which
// it will retain even if set by some constantly changing variable.
@end

You can find more about properties and fundamental Objective-C constructs here.

To add a static member:

Objective-C
// way # 1 - Button.h
@interface Button {
}
NSString *defaultText; // static
@end

To inherit from a class:

Objective-C
// Button.h
@interface Button {
	
}
@end
Objective-C
// RoundedButton.h
@interface RoundedButton : Button {
	
}
@end

Methods in Objective-C starts with + (for static or class methods) and - (for public or instance methods), followed by a return type in parentheses, method name with colon, and a list of colon separated parameters:

Objective-C
+ (int) add : (int) a : (int) b; // static or class method
Objective-C
- (int) square : (int) a; // public or instance method

Image 5

Figure - Objective-C method syntax

We cannot apply @public, @private, and @protected access specifiers to methods. Also methods can not be private, protected but we can roughly simulate this using Class Extension. To add public, private, and static methods in a class:

Objective-C
// Button.h
@interface Button {
}
@end

+ (void) setDefaultText : (NSString*) val; // static method
- (int) textLength; // public method

// Button.m
@interface Button() { // Objective-C 2.0 Class Extension
- (bool) hasDefaultText; // private method
}

@implementation Button
+ (void) setDefaultText : (NSString*) val {

}
- (int) textLength {

}
- (bool) hasDefaultText {

}
@end

To add a constructor, add a method init which returns an id object. The id object is like void*in:

Objective-C
// 1 constructor in Button.m
@implement Button
- (id) init
{
    self = [super init]; // note self == 'this' while super == 'base' in C# or C++ 

    if (self != nil) // if 'super' init returns 'nil', simply skip initialization
    {
        // your code here
    }

    return self;
}
@end
Objective-C
// 2 constructors in Button.m
@implement Button
- (id) init
{
  // default constructor
}

- (id) init : (NSString*) text
{
  // constructor with one parameter
}

- (id) init : (NSString*) text : (bool) rounded
{
  // constructor with one parameter
}
@end

Objective-C does not support method overloading. However, as the method name (or selector) in Objective-C includes parameter colons as well, it may look like method overloading but does not behave like real C++ overloading. The above constructors are not overloaded but rather three different selectors i.e., (init, init:, init::).

Image 6

Figure - Method name includes colon in Objective-C

Note that the following will give an error:

Objective-C
// 2 methods (or constructors) with same name and number of colens
@implement Button

- (id) init : (NSString*) text // 1 colen init i.e. init:
{
  
}

- (id) init : (bool) rounded // error alreay have selector init: above with 1 colen
{
  
}

@end

To create an instance of a class:

Objective-C
// 3 constructors in Button.m
@implement Button
- (id) init
{
  
}

- (id) init : (NSString*) text
{
  
}

- (id) init : (NSString*) text : (bool) rounded
{
  
}

+ (void) Tester 
{
    Button* b1 = [[Button alloc] init]; 

    Button* b2 = [Button new]; // short form of above

    Button* b3 = [[Button alloc] init: text:@"Hello world"];

    Button* b4 = [[Button alloc] init: text:@"Hello world" rounded:true];

    [b1 release];
    [b2 release];
    [b3 release];
    [b4 release];
}

@end

Calling release on an object invokes dealloc. To add, dealloc (or destructor) to free up resource:

Objective-C
// constructor & destructor Button.m
@implement Button
- (id) init
{
    _someResource = [foo retain];

    return self;
}
// destructor
- (id) dealloc
{
    [_someResource release];

    [super dealloc];
}
@end

To implement or adopt an interface (i.e., protocol) on a class:

Objective-C
// interface ITouchable.h
@protocol ITouchable 

  - (void) tap : (int) x: (int) y; // by default this method is required

  @optional 
  - (void) doubleTap : (int) x: (int) y; // a class can choose not to implement this

  @required 
  - (void) multiTap : (int) x1: (int) y1 : (int) x2: (int) y2; // explicitly required
}

// Button.h
@interface Button : NSObject<ITouchable> {
}
@end

// Button.m - Note that @optional method is not implemented
@implement Button
- (void) tap : (int) x: (int) y
{
  // default constructor
}

- (void) multiTap : (int) x1: (int) y1 : (int) x2: (int) y2
{
  // constructor with one parameter
}
@end

You can add methods to an existing class using a Category:

Objective-C
// MyNsString.h - add stripHtml() method in iOS NSString class
@interface NSString(MyNsString) {
}
- (NSString*) stripHtml;
@end

// MyNsString.m
@implement NSString(MyNsString)
- (NSString*) stripHtml
{
 
}
@end

A nice Objective-C cheat sheet by RayWenderlich is available in PDF form here.

Image 7

Figure - Objective-C Cheat Sheet

Objective-C Memory Management

There are three ways to manage memory in Objective-C:

  1. Manual Retain Release (MRR)
  2. Garbage Collection (GC)
  3. Automatic Reference Counting (ARC)

To understand existing code bases, you should get a grip on all three.

Manual Retain-Release (MRR) - 1980 - present

Image 8

Figure - MRR is the oldest memory management technology

MRR is based on a one simple rule: "If you own an object, you have to release it". You can own an object if you call a method which:

  1. begins with alloc, copy, new, init, or retain e.g. alloc, newObject, or
  2. contains Copy or Create e.g., mutableCopy.

An object that you own by the virtue of A) and B) (or ownership methods) is your 'responsibility' and you should give up ownership of object by calling release or autorelease. You must not release object for any other case.

Image 9

Figure - You should never use retainCount

When you own an object by calling ownership methods, the object's retainCount is incremented by 1 and when you call release or autorelease it is decremented by 1. When retainCount reaches to 0, object's dealloc method is called and it is destroyed. This looks simple, but you should never use retainCount because it is misleading.

Objective-C
// 1) 's' will be autoreleased and using it in calling method will result in error
- (NSString*) newStr: (NSString*) input {
    NSString* s = [NSString stringWithString:@"Hello world"];
    
    return s;
}

// 2) 's' is retained to avoid error in calling method
// calling method must call release to avoid memory leaks
- (NSString*) newStr: (NSString*) input {
    NSString* s = [NSString stringWithString:@"Hello world"];
    
    [s retain]; 
    
    return s;
}

// 3) 's' is constructed using alloc & initWithString so 
// retained is not required but calling method must call release
- (NSString*) newStr: (NSString*) input {
    NSString* s = [[NSString alloc] initWithString:@"Hello world"];
    
    return s;
}

// 4) 's' is constructed using alloc & initWithString so 
// retained is not required and calling method should not call release
// as object in put in autorelease pool and will be released automatically
- (NSString*) newStr: (NSString*) input {
    NSString* s = [[NSString alloc] initWithString:@"Hello world"];
    
    [s autorelease]; 
    
    return s;
}

// 5) 's' will be autoreleased but 's2' is a copy and its retainCount = 1
// calling method must call release to free up memory used by 's2'
- (NSString*) newStr: (NSString*) input {
    NSString* s = [NSString stringWithString:@"Hello world"];
   
    NSString* s2 = [s copy];
    
    return s2;
}

There difference between release and autorelease methods is that, release is called immediately; decrementing retainCount by 1 and calling dealloc if it becomes zero. On the other hand, autorelease just 'puts' the object in a special pool, called autorelease pool, that the Application Kit creates. autorelease pool is basically a NSAutoreleasePool object, which is created on on the main thread at the beginning of every cycle of the event loop, and drains at the end, thereby releasing any auto-released objects.

Image 10

Figure - A call to autorelease method puts an object in a special pool
Objective-C
int main(void) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    NSString *s = [[[NSString alloc] init] autorelease];
    
    [pool drain]; // release 's' as well as pool
}

If you are using GC, then drain sends message (objc_collect_if_needed) for GC while in MRR and ARC drain is same as calling release on NSAutoreleasePool.

You can nest pools and autorelease object will be added to nearest pool.

Objective-C
 int main(void) {
    NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];
    
    NSString *s1 = [[[NSString alloc] init] autorelease]; // 's' is added to 'pool1'
    
    NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];
    
    NSString *s2 = [[[NSString alloc] init] autorelease]; // 's' is added to 'pool2'
    
    [pool2 drain]; // release 's2' as well as 'pool2'
    
    [pool1 drain]; // release 's1' as well as 'pool1'
}

However recommended way is to use @autoreleasepool.

Objective-C
@autoreleasepool {
 
    NSString *s1 = [[[NSString alloc] init] autorelease]; // 's' is added to 'pool1'
 
    @autoreleasepool {
 
        NSString *s2 = [[[NSString alloc] init] autorelease]; // 's' is added to 'pool2'
 
    }
} // pool drained at the end of block

Garbage Collection (GC) - 2006 - 2011

Image 11

Figure - GC even collects cyclic object references

GC is a runtime technology and it is not available in iOS, so we will discuss it in brief. With GC, a low-priority thread collects unused objects. In GC mode, calls to own and object or release it result in no operation. For new iOS app, ARC is recommended but you can use plain-old MRR.

Automatic Reference Counting (ARC) - 2011 - present

Image 12

Figure - ARC inserts retain-release calls at compile time

ARC, available in iOS5 onwards, is a compile time technology which inserts necessary retain-release calls at the time of code compilation and sets weak references to nil once object is deallocated. This is different from GC which runs as a separate background process and collects unused objects at runtime.

ARC, however can not collect cyclic references while GC can. When using ARC, you cannot call retain, release, retainCount, autorelease, or dealloc. You can find complete list of ARC rules here.

Image 13

Figure - ARC can not handle cyclic reference automatically

In later parts of this series we will see how to develop iOS app using XCode and Cocoa framework.

Windows Phone Native App

Image 14

Figure - Windows Phone 8 on Nokia Lumia 520

Windows Phone (WP) is a mobile OS by Microsoft. WP app is developed using Windows Phone SDK and Visual Studio IDE. An XML markup language, XAML, is used to develop user interface while you can use C#, VB.NET or one of your favorite language to hook up user interface events.

Following are OS versions available on various phones:

Windows Phone release Operating system version
Windows Phone 8 Windows Phone OS 8.0
Windows Phone 7.5 Windows Phone OS 7.1
Windows Phone 7 Windows Phone OS 7.0

There is an annual fee to publish Windows Phone apps to the Windows Store.

Annual Fee

Image 15

Figure - Annual Fee

Every mobile platform provider takes some kind of annual fee:

  • To unlock certain number of mobile devices to test your app.
  • To publish paid or free app to their market place.

Here is an interesting summary:

Platform Cost per Year Test devices Limit Free apps Limit Paid apps Limit File Size Limit
Window Phone $19 (earlier $99)
DreamSpark Student = Free
3 100 Unlimited XAP = 1GB[1]
Apple iOS Developer = $99
Enterprise = $299
University = Free
 
100[2] Unlimited Unlimited IPA = 60MB[3]
EXT = 2GB
Google Play Developer = $25 (Life time) Unlimited Unlimited Unlimited APK = 50MB
EXT = 2x2GB
 
Black Berry $0 Unlimited Unlimited Unlimited COD = 128KB[4]
EXT = 14MB

[1] On most platforms anything over 20-50MB requires Wi-Fi or docked connection with laptop and can not be downloaded over-the-air data connection.

[2] Although you may remove a device from your account, Apple will continue to count it against your 100 device limit.

[3] Apple puts a 60MB limit (page 232) on executable file. Language packs, images and other resources could be bundled separately on SD card.

[4] 128KB = 64KB code + 64KB data. On all mobile platforms including Black Berry, you can download resources from a website when needed, and cache them locally on SD Card.

Image 16

Figure - SD (top), mini SD, micro SD cards

Windows Phone Project

Image 17

Figure - Windows Phone Project Types

There are many types of Windows Phone project you can start with. Let's start with Windows Phone App project to discuss some of the common Windows Phone development ideas.

A page

Usually you start Windows Phone app by adding necessary XAML files (or pages).

Image 18

Figure - What you can usually add to Windows Phone Project

An (almost) empty page will look like this. Beside having namespaces at the top, there is a Grid called 'LayoutRoot' with two rows below. The first row has "Auto" height, which means it will 'adjust' its height based on its content. The second row height is set to "*" which means it will take up 'all' available space.

XML
<phone:PhoneApplicationPage
    x:Class="PanoramaApp1.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d"
    shell:SystemTray.IsVisible="True">
 
    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
 
        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>
 
        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 
        </Grid>
    </Grid>
 
</phone:PhoneApplicationPage>

Grid Panel

Within this page you add controls inside Grid ContentPanel. Usually you will place Stack, Grid, or Canvas panel first to layout controls. Inside a panel you place actual Phone Controls e.g., Buttons, TextBlock, Textbox, etc.

XML
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
    </Grid.RowDefinitions>
    <TextBox Text="Enter User Name" Grid.Row="0" />
    <TextBox Text="Enter Password" Grid.Row="1" />
    <Button Content="Sign In" Grid.Row="2"/>
</Grid>

Image 19

Figure - Grid with two TextBoxes and a Button control

Windows Phone Toolkit

On a different note, Windows Phone Toolkit provides some really interesting controls and transitions.

Image 20

Figure - Windows Phone Toolkit

Stack Panel

Like you layout controls in a table like format using Grid panel, you can use Stack panel to place controls one on the top of other.

XML
<StackPanel>
    <TextBox Text="Enter User Name" />
    <TextBox Text="Enter Password" />
    <Button Content="Sign In" />
</StackPanel>

Canvas Panel

Or for absolute positing use Canvas panel. Note that Canvas.Top is used to specify absolute position.

XML
<Canvas>
    <TextBox Text="Enter User Name" />
    <TextBox Text="Enter Password" Canvas.Top="72" />
    <Button Content="Sign In" Canvas.Top="144" />
</Canvas>

Image 21

Figure - Controls layout using Canvas panel

Controls are kind of shrunk to default 'Auto' width because we have not specified 'absolute' width (e.g., Width="456").

Landscape Left or Right?

A mobile phone can be in one of three orientations: Portrait, Landscape (Left or Right).

Image 22

Events - Click or Tap?

You can add Button Tap event to handle Sign In. For every Tap on a mobile a Click is fired right as well with a delay of (+/-) 300 ms. So event handling in Click, will cause scrolling, cancelling, and other user interactions to feel really sluggish.

cshape
private void Button1_Tap(object sender, EventArgs e)
{
     if (MyDbContext.SignIn(this.UserNameTextBox.Text, this.PasswordTextBox.Text))
     {
       // OK: go to home page
     }
     else
     {
       // ERROR: show error popup
     }
}

Event Bubbling

Note that if Button Tap event is not available, the runtime will search parent controls until it finds an event handler.

Image 23

Figure - Windows Phone event bubbling

Windows Phone 8 supports phones that have WVGA, WXGA, and 720p resolutions. This differs from Windows Phone OS 7.1, which supported only WVGA resolution.

Navigation

A mobile application usually consists of a large number of pages and various pages are shown to end user based on his interaction of app. In Windows Phone, you can navigate and pass parameter among pages using NavigationService.

C#
// go to another page
void passParam_Click(object sender, RoutedEventArgs e)
{
   NavigationService.Navigate(new Uri("/SecondPage.xaml?msg=" + textBox1.Text, UriKind.Relative));
}

// get the parameter value
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    string msg = "";
    
    if (NavigationContext.QueryString.TryGetValue("msg", out msg))

    textBlock1.Text = msg;
}

// return back to previous page
private void button1_Click(object sender, RoutedEventArgs e)
{
    NavigationService.GoBack();
}

Panorama Control

Windows Phone Panorama Control is a way to provide a long canvas with multiple panels to host grids, text boxes, labels and other controls. Panorama control encourages the user to explore the potentially unrelated contents before going to next level of details.

Image 24

Figure - Panorama control to provide summary of unrelated contents in pages

Pivot Control

On the other hand a Pivot Control provides a way to filter related contents in pages. Checkout an email app using pivot control to filter all, unread, and flagged messages in pages.

Image 25

Figure - Pivot control to filter related items in pages

Speech Recognition

Typing in small device is a real pain. In Windows Phone, it is very easy to enable voice recognition in your application using SpeechRecognizerUI class.

C#
private async void ButtonSR_Click(object sender, RoutedEventArgs e)
{
  // Create an instance of SpeechRecognizerUI.
  this.recoWithUI = new SpeechRecognizerUI();

  // Start recognition (load the dictation grammar by default).
  SpeechRecognitionUIResult recoResult = await recoWithUI.RecognizeWithUIAsync();

  // Do something with the recognition result.
  MessageBox.Show(string.Format("You said {0}.", recoResult.RecognitionResult.Text));
}

Image 26

Figure - Windows Phone Voice Recognition Experience

Windows Phone runs only one app at a time to preserve battery and to provide resources necessary for smooth running of app. If user switch application, app state is tomb-stoned and its process is terminated except if it is an background location tracking app. When user switch back, app should restore its state from storage.

Mobile App Development - Possible Paths

Image 27

Figure - Which path is the right one?

There are three paths to develop mobile app hybrid, native and HTML 5.

Hybrid

For run-of-the-mill business applications, hybrid app provides necessary functionality and performance most of the time. A hybrid mobile app is build using HTML5, CSS3, JavaScript, PhoneGap and it runs on iOS, Android, Windows Phone and Black Berry.

Image 28

Figure - A hybrid mobile app using Knockout and ASP.NET MVC

Native

For game development that requires higher performance, graphics and lower file size, native app is the right choice but you can do game development using PhoneGap too.

HTML 5

Finally, at minimum any new website (or web app) should be build using HTML 5 and responsive layout technologies like Bootstrap or Foundation. Responsive web design gives a minimum entry point to device world which is expanding in size every day.

Do you have native platform skills?

Another factor that influences choice of path is that native app development requires skills in languages of each platform (i.e. C#, Objective-C and Java) while hybrid apps could be developed using familar CSS3, HTML5 and JavaScript. So learning curve is low for hybrid app and therefore could be developed relatively quick at lower cost.

Platform independent or specific (with high performance)?

Beside learning curve, native apps are platform specific, so you have to develop one app for each platform while hybrid apps will run on many platform e.g., iOS, Android, Windows Phone and Black Berry. However, at times clients are looking for platform specific user interface with high performance. In such cases you may want to choose native app over hybrid. If performance is not important, then mobile libraries like KendoUI Mobile, Sencha Touch and jQuery Mobile theming features provide necessary look and feel for various platforms and various versions of same platform.

When mobile app user experience matters?

Platform specific user experience is important for general purpose mobile applications released for masses. Obviously for such applications, end users do not expect iOS user interface on Android device or Android kind of user experience on Windows Phone. But for business applications targeted for a single enterprise or division, clients may opt for uniform user experience on all platforms to lower down development and training cost. If platform specific user experience is important, a better route is to select hybrid mobile framework like KendoUI Mobile.

Image 29

Figure 1 - A hybrid app on various platforms built using Kendo UI Mobile

Which platforms hybrid framework supports?

One more case where you may want to choose native over hybrid is 'platform supported'. Consider for example, Sencha Touch does not support Windows 7 Phone. To write Windows 7 specific mobile app, you may want to go for native app. See figure below for platform support by Sencha Touch:

Image 30

Image 31

Figure 1 - Limited Platform Support by Sencha Touch

PhoneGap feature support for hybrid apps

Just like platform support for hybrid framework is limited, to certain extent that is the case with PhoneGap as well. However PhoneGap 3.0 feature support is suffice for most of your needs if performance is not the key decision factor. For example, iPhone and BlackBerry Compass are inaccessible using PhoneGap while Media support is unavailable for BlackBerry, WebOS, Symbian, and Bada.

Image 32

Figure - PhoneGap 3.0 feature support for various platforms

Before you submit PhoneGap app

While submitting PhoneGap application to a market place like Apple iTunes, Google Play or Windows Phone Marketplace, you have to be cautious to include all the capabilities that are provided by PhoneGap, no matter if your application is using anyone of these or not.

Add to your application, following PhoneGap capabilities: data services, movement and directional sensor, microphone, music and video library, owner identity, camera, contacts, camera & compass. Not mentioning them will either result in application rejection or not functioning correctly on end user device.

Hopefully with these pointers, it will be easy for you to decide whether you should go for hybrid, native or HTML 5 mobile app. As most people prefer hybrid app due to low entry barrier as well as release to multiple platforms, so we will first look into hybrid mobile app technologies.

Hybrid Mobile App

Hybrid app is 'hybrid' because it uses HTML 5 & CSS3 for mobile UI and JavaScript to communicate with device SDK. 

Hybrid app = Single Page Application

Hybrid mobile app is basically a single page application (or SPA). SPA is a web application that lives within a single HTML page. The “views” of the application are injected into- and removed from the DOM as needed as the user navigates through the app. A single page application architecture is particularly well suited for mobile apps:

  • The absence of continual page refreshes provides a more fluid / closer to native experience.
  • The UI is entirely created at the client-side with no dependency on a server to create the UI, making it an ideal architecture for applications that work offline.

How PhoneGap works?

PhoneGap provides a JavaScript API phonegap-3.0.0.js to mobile app developers. This JavaScript API calls PhoneGap platform specific engine/bridge which in turn calls native platform SDK to perform actions on device. E.g., access the contact list, make a call etc. In case of Windows Phone, a PhoneGap engine/bridge is a Silverlight assembly WP7GapClassLib.dll.

PhoneGap engines are built using the native languages of each platform (C#, Objective-C and Java) which expose interfaces to the JavaScript developer. Most of the communication between PhoneGap JavaScript API and Engine occurs by setting Chrome-less browser URL.

JavaScript
gap://SomePlugin.someMethod?arg1Name=someArg1&arg2Name=someArg2

Image 33

Figure - PhoneGap application architecture

PhoneGap also provides a build system to bundle HTML 5, JavaScript and CSS3 in a Chrome-less browser i.e., a browser without any user interface.

Image 34

Figure - Phonegap build system bundles js, CSS, and HTML with Chrome-less browser

Accelerometer

Image 35

Figure - A US $35 3D Accelerometer from Dimension Engineering

Accelerometer captures device motion in the x, y, and z direction. Using PhoneGap, you can access Accelerometer mounted on iPhone, Android, Windows Phone, and Black Berry. So for example, add following configuration in App/Supporting Files/Cordova.plist to obtain permission to use iOS Accelerometer .

XML
<key>Plugins</key>
<dict>
    <key><a href="http://docs.phonegap.com/en/1.9.0/cordova_accelerometer_accelerometer.md.html#Accelerometer">Accelerometer</a></key>
    <string>CDVAccelerometer</string>
</dict>

A similar permission for Windows Phone can be obtained using a configuration Properties/WPAppManifest.xml.

XML
<Capabilities>
    <Capability Name="ID_CAP_SENSORS" />
</Capabilities>

Image 36

Figure - Accelerometer detects changes in device orientation.

Image 37

Figure - iPhone game 'Labyrinth' using Accelerometer.

Mobile Frameworks for Hybrid mobile app development

Although you can write HTML 5, CSS 3 and JavaScript and bundle it with PhoneGap to generate native image for supported platforms but people usually select some kind of mobile framework for hybrid mobile app development. This saves tons of lines of code and lots of time. Some of the popular frameworks are listed below and they vary in terms of features, platform support and adoption by community.

We will see KendoUI Mobile, Sencha Touch and jQuery Mobile in sections below which would give you an idea what is important when selecting a hybrid mobile app framework. We will take a look into other frameworks in later parts of this series.

 

1. Appcelerator Titanium Mobile

16. WebApp.net

31. The-M-Project

2. Apache Flex

17. XUI

32. NimbleKit

3. GWT mobile webkit + gwt mobile ui

18. Zepto.js

33. Mono for Android

4. CNET iPhone UI

19. ChocolateChip-UI

34. MonoTouch

5. iPhone Universal

20. Application Craft

35. qooxdoo

6. Jo HTML5 Mobile App Framework

21. DHTMLX Touch

36. ShiVa 3D

7. iUI

22. Corona

37. RareWire

8. JQ Touch

23. eMobc

38. V-Play

9. jQuery Mobile

24. Dojo Mobile

39. NSB/AppStudio

10. mobione

25. Marmalade

40. AppConKit

11. Phone Gap

26. Kendo UI

41. Trigger.io

12. Quick Connect

27. Handheld Designer

42. wink

13. Rhodes

28. Mobify.js

43. ViziApps

14. Sencha Touch

29. iWebKit

 

15. TapLynx

30. Moai

 

jQuery Mobile - Hybrid Mobile App Framework

jQuery Mobile is easy to learn mobile framework with large community support and mobile widgets. It does not have a steep learning curve like Sencha Touch ($595) and may be KendoUI mobile ($699). Though there are performance concerns while loading a list view with 50-60 items, as jQuery Mobile app gets sluggish (and even crash mobile browser). Sencha Touch on the other hand could load 200+ items without any performance issues.

jQuery Mobile 1.3.2 consists of JavaScript (147KB), CSS (92KB), images (~6.6MB zip) and uses core jQuery 1.10.2 library (91KB). Size is a concern on a device with limited RAM and CPU power to parse JavaScript. Size effect could be minimized using Google Closure Compiler, minify, or yui compressor which strips off unreachable JavaScript code. We will deal with optimizations in a separate article. For right now let's focus on mobile app frameworks.

Image 38

Figure - Closure results in much smaller version of the JavaScript code that functions identically to the original

To design jQuery mobile pages, a handy codiqa designer is available at jQuery Mobile. Once page HTML, CSS and JavaScript is designed, it can downloaded in zip form. It may be helpful to remember that jQuery UI (a jQuery widgets library for desktop web apps), can not be used with jQuery Mobile due to CSS conflicts. So all you have are either jQuery Mobile widgets or community built widgets.

Image 39

Figure - Codiqa to build mobile UI

To draw above login UI, all you need is to write familiar HTML with jQuery CSS and data attributes. data-attribute is HTML 5 feature which let you define as many data- prefixed attributes on elements to 'store any information' and they will not effect on page layout. Note that data-role attribute on <div> makes it a container for label and textbox.

KendoUI Mobile - Hybrid Mobile App Framework

KendoUI mobile is an MVVM based mobile app framework with charting and some really useful mobile widgets that comes at $699. KendoUI supports model binding like Knockout which saves you from writing tons of lines of code.

Image 40

Figure - KendoUI mobile provides widgets and framework to build hybrid mobile app

To achieve fluid layout for mobile platforms, use KendoUI with layout libraries like Bootstrap or Foundation as it is not a layout library. KendoUI has lower learning curve as compared to Sencha Touch which is all JavaScript, but provides great flexibility and performance with MVC architecture.

KendoUI Hierarchical ListView, ActionSheet and ListView controls provide a great way to list down items while Tablet SplitView control is an excellent way to to show master-detail scenarios on tablets.

Image 41

Figure - KendoUI mobile ActionSheet control with iPhone theme

Image 42

Figure - KendoUI mobile ListView control with Windows Phone theme

Image 43

Figure - KendoUI mobile SplitView control for Tablets with Android theme

KendoUI Mobile theme builder can be used create platform specific themes:

Image 44

Figure - Kendo UI Mobile Theme Builder

For performance and flexibility reasons, the Kendo UI mobile iOS theme does not use any images. The UI elements are built with CSS effects only so apps look slightly different from an actual iOS application.

KendoUI provides data visualization capabilities by drawing interactive graphs using its dataviz components. To draw graphs, KendoUI automatically detects browser capabilities and use SVG (or VML as fallback). IE6, IE7, and IE8 only support VML; IE9 supports some SVG; the other major browsers support SVG.

Image 45

Figure - KendoUI mobile dataviz graphs

Sencha Touch - Hybrid Mobile App Framework

Sencha Touch provides ultimate performance at the cost of complexity and steep learning curve. Sencha Touch is MVC and all JavaScript and it may be confusing for a web developer and little less to Java/C# developer. But this learning cost comes with a benifit of massive performance improvement which is questionable in jQuery Mobile apps.

As Sencha Touch was initially targeted for iOS and later added the support for Android, Black Berry and Windows Phone, so you could expect performance will not be same on all platforms.

Sencha Touch has a bag full of mobile widgets like Navigation View & Carousel and a power layout library.

Image 46

Figure - Sencha Touch Carousel View control

Sencha Touch has native packaging and deploy system just like PhoneGap. So, in a way you could build end-to-end cross platform solution using just Sencha Touch without employing PhoneGap.

HTML 5 Responsive Website

We have already discussed this kind of application development in Part 1. However let's touch couple of more concepts here that are important to mobile website development.

Mobile Browsers

Mobile browsers are different from desktop browsers as they support two Viewports i.e., Layout and Visual. Layout viewport is the one that is used for all CSS calculation while visual viewport is the part of html document currently on device screen. They Layout view port is different in width per browser. Safari iPhone uses 980px, Opera 850px, Android WebKit 800px, and IE 974px. On BlackBerry the layout viewport equals the visual viewport at 100% zoom. This does not change.

JavaScript
window.innerWidth // and innerHeight for visual viewport dimensions
document.clientWidth //and clientHeight for layout viewport dimensions

Image 47

Figure - Mobile browsers support two viewports - Layout and Visual

Hash Fragment

Image 48

Figure - Hash fragment to index AJAX based Websites

Most mobile website are AJAX based to load contents when needed. In a typical website, URL is a way to bookmark and share contents you like as well as a way for search engines to index your website. However AJAX based websites like Twitter and Facebook download an initial JavaScript which makes AJAX calls to get further contents. The problem with crawlers (like Google) is that they do not parse JavaScript or make AJAX calls and therefore can never see the same page which user see. This results in poorly indexed website.

To create a URL that return HTML snapshot to crawlers instead of JavaScript, hash fragments (i.e., #!) are used. A URL http://twitter.com/#!/mashable or www.example.com/ajax.html#!key=value on AJAX website or single page applications, returns static HTML to crawler which improves site indexing.

What's Next

In the next update of this article, we will explore capabilities of various mobile platforms further. We will also take a look into iOS, Android, WP, and BlackBerry development and write code use device capabilities.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)