About the Author

Software Engineer @ Interknowlogy

How to use PhoneGap API + iOS, Android

Last blog post I showed how to use PhoneGap’s API with Windows Phone 7. For this blog post, I will use the same web files (HTML and Javascript files) and create an iOS and Android application.

How to setup dev environment?
First thing to get started is visit PhoneGap’s website where they have instructions on how to setup your environment to create an iOS and Android app with PhoneGap. Just select your platform and the instructions will update update on the page for that environment.

After you have your iOS and Android environment setup using Xcode and Eclipse, copy the web files into the “www” folder for each project. Below is a screen shot of the project navigator or package explorer inside Xcode and Eclipse.

Package Explorer in Eclipse for Android Project Navigator in Xcode for iOS

Since I’m reusing the web files, all the code is exactly the same across the Android, iOS and Windows Phone 7 app. So, I’ll just show a few of the pages/screens in the iPhone simulator and Android simulator.

Device Screen (Android) Device Screen (iPhone)
Notification Screen (Android) Notification Screen (iPhone)

Click here to download the iOS example project.
Click here to download the Android example project.

How to use PhoneGap API + WP7

How to get started?

In my previous blog posts I’ve shown how to use PhoneGap with Xcode and Eclipse in targeting iOS and Android platforms. For this blog post, I will show how to use the PhoneGap API with Visual Studio and the Windows Phone 7 emulator as your development environment.

For this sample project, we will also be using JQuery and JQuery Mobile UI.

Now to get started, PhoneGap has documentation on what tools to download and what steps to follow. After you have your development environment setup, you can look over PhoneGap’s API documentation. The API is not to cumbersome and is straight-forward in following for each of the different device hardware. Most of the API involvrs javascript callbacks as I will show below in example code.

For this blog post, I will discuss how to use the following:
1. Device
2. Accelerometer
3. Camera
4. Geolocation
5. Notification

Most of the API methods and objects will exist on most of the major platforms (iOS, Android, WP7). However, some things will be specific on some platforms. Android and WP7 has a search and back button but iOS doesn’t. The menu button only exists on Android. In general, you should be able to use the PhoneGap universally on all platforms. But its good practice to test and run on each device to make sure it works they way you expect.

The sample project was developed fully in Visual Studio and tested with the Windows Phone 7 emulator. The 5 device hardware features that I will interact with using the PhoneGap API is shown on their own phone screen. The examples are very simple to explain how to use the PhoneGap API.

Below is a screen shot of the sample project’s Solution Explorer in Visual Studio. Notice the “www” folder. This folder is created with the PhoneGap project template and where all your web files (HTML, CSS, JavaScript, etc) exist.

Solution Explorer

Before we dive into the API code for each phone screen, I want to mention when using the PhoneGap API you should place your javascript code inside the javascript event OnDeviceReady. If you place your javascript code that calls the PhoneGap API in here, you can guarantee the device is loaded and ready to interact with. Below is the code included in the index.html file.

        <script type="text/javascript">

        document.addEventListener("deviceready", onDeviceReady, false);

        // once the device ready event fires, you can safely do your thing! 
        function onDeviceReady() 
        {

        }
        </script>

Now lets dive into example code.

Device – Gather device specific information

The HTML and jQuery Mobile UI for the Device screen.

<body>
    <div id="home" data-role="page">
        <div data-role="header">
            <h1>Device</h1>
            <a href="#accelerometerpage" data-icon="add">Next</a>
        </div>
        <div data-role="content">
            PhoneGap Device API
            <!--<a href="#newpage" data-role="button">Second Page</a>
            <br/>-->
            <p id="devicename"></p>
            <p id="devicephonegap"></p>
            <p id="deviceplatform"></p>
            <p id="deviceuuid"></p>
            <p id="deviceversion"></p>
        </div>
    </div>
</body>

The jquery code inside onDeviceReady. The device object is from PhoneGap’s API and its value is added to the innerthtml for each #device element.

        <script type="text/javascript">

        document.addEventListener("deviceready", onDeviceReady, false);

        // once the device ready event fires, you can safely do your thing!
        function onDeviceReady() 
        {
            console.log("onDeviceReady. You should see this message in Visual Studio's output window.");

            $('#devicename').html(device.name);
            $('#devicephonegap').html(device.phonegap);
            $('#deviceplatform').html(device.platform);
            $('#deviceuuid').html(device.uuid);
            $('#deviceversion').html(device.version);
        }
    </script>

The HTML and jQuery Mobile UI for the Accelerometer screen.


      <div id="accelerometerpage" data-role="page">
        <div data-role="header">
            <a href="#home" data-icon="back">Back</a>
            <h1>Accelerometer</h1>
            <a id="camerabutton" href="#camerapage" data-icon="add">Next</a>
        </div>
        <div data-role="content">
            PhoneGap Accelerometer API
            <p id="aX"></p>
            <p id="aY"></p>
            <p id="aZ"></p>
            <p id="aTime"></p>
        </div>
    </div>

The jquery code inside onDeviceReady. The navigator object is from PhoneGap’s API. Here the navigator object calls the watchAcceleration method where the first input is the success callback method, the second parameter is the error callback method and the third parameter is the frequency in millisections the success callback method will fire.

var watchId = navigator.accelerometer.watchAcceleration(onAccelSuccess, onError, { frequency: 1000 });

        function onAccelSuccess(a) {
            $('#aX').html(a.x);
            $('#aY').html(a.y);
            $('#aZ').html(a.z);
            $('#aTime').html(a.timestamp);
        }
        
        function onError() {
            // TODO: write error logic
        }

The HTML and jQuery Mobile UI for the Camera screen. Here we will write to the imageuri the fileURI of the image we capture. It will write out the location and filename of the image.

      <div id="camerapage" data-role="page">
        <div data-role="header">
            <a href="#accelerometerpage" data-icon="back">Back</a>
            <h1>Camera</h1>
            <a href="#geolocationpage" data-icon="add">Next</a>
        </div>
        <div data-role="content">
            PhoneGap Camera API
            <p id="imageuri"></p>
        </div>
    </div>

The jquery code inside onDeviceReady. The navigator object calls camera then the getPicture method. The input parameters are similar to the Accelerometer except the third parameter where we define inline the quality, destinationType and Camera.DestinationType.FILE_URI. The file_uri that is returned in the success callback method will be added to the innerhtml at imageuri.

navigator.camera.getPicture(onCameraSuccess, onError, { quality: 50, destinationType: Camera.DestinationType.FILE_URI });

        function onCameraSuccess(fileUri) {
            $('#imageuri').html(fileUri);
        }

The HTML and jQuery Mobile UI for the Geolocation screen. Similar to the Accelerometer screen, we will write the lat/lon values to the innerhtml.

      <div id="geolocationpage" data-role="page">
        <div data-role="header">
            <a href="#camerapage" data-icon="back">Back</a>
            <h1>Geolocation</h1>
            <a href="#notificationpage" data-icon="add">Next</a>
        </div>
        <div data-role="content">
            PhoneGap Geolocation API
            <p id="lat"></p>
            <p id="lon"></p>
        </div>
    </div>

The jquery code inside onDeviceReady. Here we’re calling the watchPosition of geolocation object and on the success callback method retrieving the lat and lon values.

navigator.geolocation.watchPosition(onGeolocationSuccess, onError, { frequency: 1000 });

        function onGeolocationSuccess(p) {
            $('#lat').html(p.coords.latitude);
            $('#lon').html(p.coords.longitude);
        }

The HTML and jQuery Mobile UI for the Geolocation screen. Here we created an anchor tag that will look like a mobile button that will display a PhoneGap notification alert.


      <div id="notificationpage" data-role="page">
        <div data-role="header">
            <a href="#geolocationpage" data-icon="back">Back</a>
            <h1>Notification</h1>
            <a href="#storagepage" data-icon="add">Next</a>
        </div>
        <div data-role="content">
            PhoneGap Notification API
            <br/>
            <a id="notificationbutton" href="" data-role="button">Click Me!</a>
        </div>
    </div>

The jquery code inside onDeviceReady. Here we use jquery to create a handler for notificationbutton that will call PhoneGap’s API object navigator.notification.alert. When the success callback method is reached it will update the innerhtml text of the button to Clicked.

            $('#notificationbutton').click( function() {
                navigator.notification.alert("You clicked me!", onNotificationSuccess, "Click", "Ok");
            });

        function onNotificationSuccess()
        {
            $('#notificationbutton').html('Clicked');
        }

I hope this helps in getting started with PhoneGap’s API. There is a lot more that can be discussed.

Here is the code for the sample project.

Introduction to Moq Framework

I have been using Moq for a few weeks now for a current project at work. I have looked at other mock frameworks for unit testing and have pleasantly been enjoying Moq. Let me first describe what Moq is.

What is Moq?
Moq is promoted by its creators as easier to learn and use than other Mock Object Frameworks such as Rhino Mocks and TypeMock Isolator. Moq is the only mocking library for .NET developed to take advantage of Linq expression trees and lambda expressions. Thus making it the most productive, type-safe and refactoring-friendly mocking library available.

Moq supports mocking interfaces as well as classes. There are some requirements and limitations on classes. The class can’t be sealed. Also, the method being mocked must be marked as virtual. You cannot mock static methods.

The emphasis on lambdas enables Moq to provide a very clean syntax for representing expectations, parameter constraints, and return values. The name “Moq” comes from a combination of Mock and Linq, even though it truly uses lambdra expressions instead of Linq as you will see below in examples.

Moq uses Castle DynamicProxy internally as the interception mechanism to enable mocking. It’s merged into Moq binaries, so you don’t need to do anything other than referencing Moq.dll.

Moq Features
Moq offers the following features according to Moq’s Google code web site

1. Strong-typed: no strings for expectations, no object-typed return values or constraints
2. Unsurpassed Visual Studio intellisense integration: everything supports full Visual Studio intellisense, from setting expectations, to specifying method call arguments, return values, etc.
3. No Record/Replay idioms to learn. Just construct your mock, set it up, use it and optionally verify calls to it. You may not verify mocks when they act as stubs only, or when you are doing more classic state-based testing by checking returned values from the object under test.
4. Granular control over mock behavior with a simple MockBehavior enumeration. No need to learn what’s the theoretical difference between a mock, a stub, a fake, a dynamic mock, etc.
5. Mock boths interfaces and classes
6. Override expectations: can set default expectations in a fixture setup, and override as need on tests
7. Pass constructor arguments for mocked classes
8. Intercept and raise events on mocks
9. Intuitive support for out/ref arguments

Most of the above features I will demonstrate with example code below.

Now to some code. Assume you have a Product that you want to test against. That Product has an Id and Name and is stored somewhere in a repository. To keep things simple, we will be using Moq and testing against IProduct and IProductRepository.

    public interface IProductRepository
    {
        List<IProduct> Products();
        IProduct GetProduct(int id);
    }

    public interface IProduct
    {
        int Id { get; set; }
        string Name { get; set; }
    }

So, let’s simply mock our Product using Moq. Then assign values to Id and Name properties.

            // Mock a product
            var newProduct = new Mock<IProduct>();

            // stub all properties on a mock
            newProduct.SetupAllProperties();

            // Calls Id property and returns 1
            newProduct.SetupGet(p => p.Id).Returns(1);
            // Calls Name property and returns "Bushmills"
            newProduct.SetupGet(p => p.Name).Returns("Bushmills");

Now lets test the values we expect are actually stored in each of the properties.

            // Tests Id property returns 1
            Assert.AreEqual(newProduct.Object.Id, 1);
            // Tests Name property returns "Bushmills"
            Assert.AreEqual(newProduct.Object.Name, "Bushmills");

            newProduct.Object.Name = "Bushmills";
            // Verify that "Name" property is set with any value
            newProduct.VerifySet(x => x.Name);
            // Verify that "Name" property is set to "Bushmills"
            newProduct.VerifySet(x => x.Name = "Bushmills");
            // Verify that "Name" property starts with "Bush" value
            newProduct.VerifySet(x => x.Name = It.Is<string>(s => s.StartsWith("Bush")));

The above example just touches the surface what Moq can help you in unit testing your code. Next example shows how to verify a method is called in your class and how many times it was called.

Below is what we are using. It’s simply a Order class that you can define with an Id and Total. It has a method WriteMethod that string formats your Id and Total together.

    public class Order
    {
        public int OrderId { get; set; }
        public decimal OrderTotal { get; set; }
        public void WriteOrder(IFileWriter fileWriter)
        {
            fileWriter.WriteLine(String.Format("{0}, {1}", OrderId, OrderTotal)); // formats to "1001, 10.53"
        }
    }

Notice in WriteOrder it has a type IFileWriter as an input parameter. Let’s define that below.

    public interface IFileWriter
    {
        void WriteLine(string line);
    }

Now, let’s start using Moq to test and verify that WriteLine was called in IFileWriter through calling WriteOrder in Order. Confused? Hopefully the code below will make things start clicking. First let’s initialize Order and create a mock for IFileWriter

            // Initialize Order
            Order order = new Order() {OrderId = 1001, OrderTotal = 10.53M};

            // Create a mock with Moq
            Mock<IFileWriter>  mockFileWriter = new Mock<IFileWriter>();

            // Call "WriteOrder" method to format the string
            order.WriteOrder(mockFileWriter.Object);

Now lets use Moq to verify if WriteLine was ever called.

            // verify that the "WriteLine" method was called from the interface with the exact input "1001, 10.53"
            // the lambda expression is not really executing
            // it is being turned into an expression tree and then analyzed by Moq, not actually being executed
            mockFileWriter.Verify(fw => fw.WriteLine("1001, 10.53"), Times.Exactly(1));

            // verify that the "WriteLine" method was called from the interface with any input string
            mockFileWriter.Verify(fw => fw.WriteLine(It.IsAny<string>()), Times.Exactly(1));

            // verify that the "WriteLine" method was called from the interface with  input string that starts with "1"
            mockFileWriter.Verify(fw => fw.WriteLine(It.IsRegex("^1001")), Times.Exactly(1));

            // verify with predicates
            // veirfy that the "WriteLine" method was called from the interface with input string  that is longer than 3 characters
            mockFileWriter.Verify(fw => fw.WriteLine(It.Is<string>(s => s.Length > 3)), Times.Exactly(1));

So far in the above two examples I’ve shown how to verify properties and methods in concrete classes. Now let me show you an example in using Moq to mock a return value for a method signature in an interface. Then using that expected return value in a method to verify a sum. The example below is a TaxProduct that has its price calculated with a Tax Calculator.

    public class TaxProduct
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public decimal RawPrice { get; set; }
        public decimal GetPriceWithTax(ITaxCalculator calculator)
        {
            return calculator.GetTax(RawPrice) + RawPrice;
        }
    }

    public interface ITaxCalculator
    {
        decimal GetTax(decimal rawPrice);
    }

First, lets mock our tax calculator:

            // Initialize our tax product
            TaxProduct tp = new TaxProduct() {ID = 1, Name = "Tax Product 1", RawPrice = 25.0M};

            // Create a mock with Moq
            Mock<ITaxCalculator> fakeTaxCalc = new Mock<ITaxCalculator>();

Now when we call GetTax from our mock object, let’s expect a return value of 5M. Then let’s call GetPricedWithTax and verify that GetTax method was called exactly once.

            // make sure to return 5$ of tax for a 25$ tax product
            fakeTaxCalc.Setup(tax => tax.GetTax(25.0M)).Returns(5.0M);

            // state or behavior verification?
            // retrieve the calculated tax
            decimal calculatedTax = tp.GetPriceWithTax(fakeTaxCalc.Object);

            // verify that the "GetTax" method was called from the interface
            fakeTaxCalc.Verify(tax => tax.GetTax(25.0M), Times.Exactly(1));

Now lets make sure the calculated price equals your product price (25.0M) with tax added (5.0M) which should sum to 30.0M.

            // retrieve the calculated tax
            calculatedTax = tp.GetPriceWithTax(fakeTaxCalc.Object);

            // Make sure that the taxes were calculated
            Assert.AreEqual(calculatedTax, 30.0M);

I hope this helps others with an introduction of using Moq to add code coverage in your projects using unit tests.

Here is a link to all the example code

How to use PhoneGap to port quickly your web app to a native iOS and Android device

This blog post will show how to take a web site written only in HTML5, CSS3 and JavaScript and quickly develop an iOS and Android mobile application. In order to do this, I will use Adobe PhoneGap, a mobile web frame to build cross-platform mobile applications. As mentioned in my previous blog post, PhoneGap is an HTML5 app platform that allows you to author native applications with web technologies. Even though my blog post will only show how to develop an iOS and Android application, PhoneGap also supports developing BlackBerry, webOS, Windows Phone 7, Palm devices, etc. In a nutshell, you’ll be using a PhoneGap wrapper that contains your web-based HTML, CSS and JavaScript code. Also, you will gain access to many of the device’s native features such as the compass, camera, the contacts list, accelerometer, etc.

PhoneGap introduced last year PhoneGap Build which offers a cloud-based service that takes your app written in HTML5, CSSe and Javascript and sends you back app-store ready apps for iOS, Android, Palm, Symbian and the other mobile platforms. Check out pricing and other details on their web site.

Below is a general process involved in getting setup using PhoneGap and developing an application:

1. PhoneGap has a great Getting Started tutorial for all the mobile platforms. Download the PhoneGap tools and the specific set of tools for the platforms you’re working with. For example, download Xcode and iOS SDK if you plan on porting your web site to an iOS application. Download the Android SDK and Eclipse if you plan on making an Android application.

2. Install all the platform tools and PhoneGap to your existing environment.

3. Start developing your web application and test with a web browser of your choice. I normally use Visual Studio to write my web application and test it using Safari, Chrome or any webkit supported browser. Since these are the types of browsers on smartphones. I would take advantage of Visual Studio’s IDE in debugging my javascript code or Web Inspector in Safari or the dev tools found in FireFox or Chrome.

4. Once you’re ready to port it to a mobile application, you will put all your web files within the www folder. For Xcode, all you need to do is create a new project using the PhoneGap template. Once the project is created, immediately compile the project. Once the project is done building, a www folder will be created in your project folder. Add the www folder into the project navigator. This is where you will house all your web files (HTML5, CSS3 and Javascript files). Run your project and you should see your web page displayed in the iPhone or iPad simulator.

5. For Android, install Android SDK, Eclipse and then the Android plug-in for Eclipse. Create an Android project in Eclipse and follow these steps to modify the project to support PhoneGap. Then run the project and select an Android Virtual Device (AVD) to use as the emulator to display your application.

6. Steps 4 and 5 can be done for you using PhoneGap Build. Just upload your web application files using their Cloud service and they will send you back app-store ready packaged files for the mobile platforms they support.

7. A noteworthy caveat is you will have to tweak some of your web language code depending on which mobile platform you choose. Not all mobile devices are similar in hardware but PhoneGap does an excellent job in pointing out issues through their API Docs section on their web site.

For step 5, here are some links to great tutorials on how to Get Started in developing for Android:
1. Getting Started With Android Development Using Eclipse
2. Getting Started with Android on a Mac
3. Running Android SDK Examples Using Eclipse

So below is a web page example written only in HTML5, CSS3 and Javascript. The HTML consists of an input element and a button. Using JavaScript, it dynamically shows in an unordered list the input values you submit. If you click any of the list items in the unordered list, it will make a call using the Twitter Search API and return the latest tweet with that keyword as an input parameter.

HTML elements:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    <body>
	<div id="main">
        <h1>Search Twitter</h1>
        <form id="foodForm">
            <input type="text" id="foodName" placeholder="keyword" />
            <button id="submitFood">Tell Us!</button><br>
        </form>
        <ul id="foodList">
        </ul>
        </div>
   </body>
}

JavaScript code event handler when DOM is loaded:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    document.addEventListener("DOMContentLoaded", function () {
            //navigator.notification.alert("I think today will be a great day.", function() {}, "Great Day");
            // uncomment below code to clear items in LocalStorage
            //window.localStorage.clear();
            // <ul> instance variable
            var foodList = document.getElementById('foodList');
            // textbox instance variable
            var foodField = document.getElementById('foodName');

            // length of food items in localStorage
            var l = window.localStorage.length;
            var i = 0;
            var storedFoodName;


            // add food item to <li> child
            function addNewFoodItem(foodName) {
                var newFoodItem = document.createElement('li');
                newFoodItem.innerHTML = foodName;
                foodList.appendChild(newFoodItem);
            }

            // loops through localStorage for food items and calls addNewFoodItem function
            for (i; i < l; i++) {
                storedFoodName = window.localStorage.key(i);
                if (storedFoodName.match(/^food[.]/))
                    addNewFoodItem(window.localStorage.getItem(storedFoodName));
            }
}

Javascript code that gets handled when the button is clicked:

document.getElementById('foodForm').addEventListener('submit', function (evt) {
                evt.preventDefault();
                var newFood = foodField.value;

                // creates a foodKey value with food.[length]
                var foodKey = "food." + (window.localStorage.length + 1);
                // calls addNewFoodItem function
                addNewFoodItem(newFood);
                // saves foodKey and input food to localStorage
                window.localStorage.setItem(foodKey, newFood);

                // clears foodFied variable
                foodField.value = "";
                return false;

            }, false);
        });

Javascript code that calls the Twitter Search API remote service using the XMLHttpRequest object and parses the JSON data returned. It displays the latest tweet in a notification alert after you click on the ListItem in the unordered list.

// callback function to get the latest tweet
        function getLatestResult(JSONstring) {
            var twitterPayload = JSON.parse(JSONstring);
            var latestResult = twitterPayload.results[0];

            return latestResult;
        }

        // performs a get request for url
        // passes the response text to callback
        function getXHR(url, callback) {
            var req = new XMLHttpRequest();
            req.onreadystatechange = function () {
                if (this.readyState == 4) {
                    if (this.status == 200 || this.status == 0) {
                        callback(this.responseText);
                    } else {
                        console.log('something went wrong');
                    }
                }
            }
            req.open('GET', url, true);
            req.send();
        }

        // event handler for the clicks on <li> elements using event delegation to catch all of these events.
        // We listen on the document element, and then, if the target of the event matches one of our list items, 
        // fires the event handler
        document.addEventListener("click", function (evt) {
            if (evt.target.tagName == 'LI') {
                // gets the selected <li> element
                var foodSubject = evt.target.innerHTML;
                var foodSearch = encodeURIComponent(foodSubject);
                // generates twitterURL for Twitter Search API
                var twitterUrl = 'http://search.twitter.com/search.json?q=' + foodSearch;

                // calls getXHR function to get latest tweet of selected <li> element 
                // then calls callback function to pop-up an alert msg with latest tweet
                getXHR(twitterUrl, function (response) {
                    var latestTweet = getLatestResult(response);
                    var msg = 'Latest Tweet about ' + foodSubject + ' from ' + latestTweet.from_user + ': ' + latestTweet.text;
                    //navigator.notification.alert("PhoneGap is working")
                    alert(msg);
                })
            }

        }, false);

Project Navigator in Xcode

Project Navigator in Xcode for PhoneGap project

iPhone Simulator of Search Twitter

iPhone emulator of PhoneGap application

Project Explorer in Eclipse

Project Explorer of Android project in Eclipse. Notice the /assets/www folder and /libs folder with PhoneGap related web files

Android Virtual Device

Android Virtual Device running the web page

PhoneGap is good at helping developers leverage their experience at building web applications using web standards, HTML, CSS and JavaScript. If you know web standards, you’ll experience few problems while working with PhoneGap. All you need to learn is how to use the PhoneGap API. Once you become familiar with the PhoneGap API, you can quickly take advantage of accessing the device’s camera, pull up the contacts or work with the accelerometer or compass.

As the web site example above shows, if you need to connect your application with a remote web service, you can easily bring in tools like jQuery to create powerful Ajax handlers. Or as I demonstrate in how to use XmlHttpRequest objects.

As I pointed out in step 7 above, just because you code a web application using PhoneGap and it works on an iPhone device, it doesn’t automatically mean that it will work on other devices. You will have to test and tweak for the other devices that are supported.

If you want to port to multiple devices, you will need separate environments for each wrapper. For example, you won’t be able to maintain your Android PhoneGap wrapper with Xcode. I used my Mac and have installed Xcode and Eclipse but I make sure I keep them in separate environments.

PhoneGap, Appcelerator and mobile web frameworks

What are mobile web frameworks

What are web based application frameworks? First, there are many out there including PhoneGap, Appcelerator, etc. For developers struggling to learn Objective-C, Java, etc these frameworks allow you to still build mobile applications. Essentially, these frameworks exist to help developers that come from a web development background with a set of tools to use with their current skillset (HTML, CSS and Javascript) to build native or native-like mobile applications. PhoneGap and Appcelerator Titanium are the most popular amongst all the frameworks out there on the interweb. For this blog post, I want to compare and contrast the two along with other mobile frameworks. Hopefully this will help you if you’re deciding on which framework to architect your next project.

PhoneGap is developed by Nitobi Software which was recently acquired by Adobe. On their website, it says “Build apps in HTML and Javascript and still take advantage of core features in iPhone/iPod touch, iPad, Google Android, Palm, Symbian and Blackberry SDKs.” Currently, PhoneGap v1.3 supports 7 different platforms including iOS, Android, Palm, WebOS, WP7, Symbian and Bada. The framework is open source which means developers and companies can use PhoneGap for mobile applications that are free, commercial, open source, or any combination of these.

What is required to use PhoneGap

PhoneGap projects require the underlying SDKs (e.g. iOS 5 SDK) to be installed and building the project happens from an IDE, such as Xcode 4. Once you have Xcode and iOS 5 SDK installed, download PhoneGap and install it. Open up Xcode and under the New Project dialog, there should be a PhoneGap-based Application project template as shown in Figure 1.

New Project Dialog

Figure 1

After installing the PhoneGap project template, make sure to build and launch the iPhone simulator. You should see an error in your simulator informing your “index.html” was not found as shown in Figure 2.

iPhone Simulator Error

Figure 2

In order to fix this, go ahead and copy the ‘www’ directory to the Project Navigator in Xcode. The ‘www’ folder exists in the PhoneGap project folder location. You can quickly go to that folder by right-clicking on the project root in Project Navigator and selecting “Show In Finder”. After you drag the ‘www’ folder, you should see a prompt as shown in Figure 3. Select “Create folder references for any added folders” and click Finish.

Folder Reference

Figure 3

Your Project Navigator should look similar to Figure 4.

Project Navigator

Figure 4

Now rebuilt and run the iPhone simulator again and you should see similar to Figure 5

iPhone Simulator

Figure 5

Basically, the developer puts his files (HTML, CSS or Javascript) into a ‘www’ folder in the project directory. When building, PhoneGap then renders these files inside a native WebView provided by the OS-specific language (either Objective-C or Java), it exposes access to certain native device features, like Accelerometer, Camera, Notifications, etc.

In a nutshell, a PhoneGap application is essentially still a web application, wrapped inside a WebView. It still remains a web application that is displayed through rendering of HTML, CSS and Javascript using a browser instance on a mobile device.

Appcelerator Titanium

Appcelerator Titanium is another mobile framework to help developers build mobile applications but only on iOS and Android at this time. Similar to PhoneGap, Titanium provides a binding layer that maps Javascript function calls to natively available APIs.

However, Appcelerator claims to be different than PhoneGap in translating Javascript code to native application code. The Javascript code is being interpreted during runtime and through a bridge layer, function calls to Titanium.some_function invoke native application code under the hood.

Another way Appcelerator is different is up until the latest version of Appcelerator, v1.5, you would write your application code in HTML, CSS and Javascript. Now, the application code is written in pure Javascript, using mainly functions that the Titanium API exposes. Apart from using it to access special device features (Camera, Accelerometer, etc), it also enables the developer to render native UI elements (buttons, tables, etc).

These differences give Appcelerator an edge of performance. Just want to emphasize, all the application code will be in Javascript, even the styling of elements happens through function calls. One thing to also keep in mind is to ask yourself will the Javascript API provide all the functionality needed in your application.

Unlike PhoneGap, building and packaging your application does not happen inside an IDE (Xcode, Eclipse, etc), but through their software, Titanium Developer. This is the tool to set up new projects, configure, test and package them. Any IDE of your choice can be used to write the application code.

When choosing a mobile web framework, keep in mind it depends on the requirements of the application when choosing which framework to go with. If the goal is to target many platforms as possible, then PhoneGap may be the right choice. If true native-ness and performance is important, then Titanium may be the choice.

There are many other mobile web frameworks out there that are open source and free and some that charge a developers license fee. I would like to write a follow up blog post on MonoTouch, NimbleKit, AppMobie and others. Stay tuned.

Introduction to iOS 5 Storyboards Part 2

Passing Data from One Screen to Another

This post continues from How To Use iOS 5 Storyboard Part 1 and uses the same project, StoryboardSample. Right now we have a two view controllers in our storyboard. When a user clicks on the button, the screen navigates to the second controller. Now we want to pass data from one scene to another using storyboards.

Passing Data From One Screen to Another

When a transition is happening from one scene to another, the storyboard runtime creates a segue object for that transition. A segue is an Objective-C object. It is an instance of class UIStoryboardSegue. A segue is represented in the Storyboard canvas.

When a transition happens, the current view controller will receive the prepareForSegue:sender: message where the prepareForSegue parameter will be an object of type UIStoryboardSegue. If you want to pass any data from the current view controller to view controller which is about to appear on the screen, you need to do that in the prepareForSegue:sender: method.

1. Add the following prepareForSegue:sender: method in the first view controller:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSLog(@"Source Controller = %@", [segue sourceViewController]);
    NSLog(@"Destination Controller = %@", [segue destinationViewController]);
    NSLog(@"Segue Identifier = %@", [segue identifier]);
}

If you run this app now, you will see the results in the console window. However, the identifier variable is nil. Each segue has an identifier which can uniquely identify that segue.

Since one scene can have more than one segue associated with it, it is good to give your segues identifiers that you can then detect in your view controllers and take action accordingly.

A segue object in IB is the connection between two scenes as shown in Figure 1.

Segue arrow

Figure 1

Follow these steps to give your segue an identifier:

1. Select your segue object in IB
2. From the View menu, select Utilities->Show Attributes Inspector
3. In the Attributes Inspector, in the Identifier text field, write text for the identifier value for this segue. I named the identifier, SegueId1. Press Enter.

Also, add a second view controller to the project navigator. Follow the following steps to add a view controller to your existing project.

1, Go to File -> New -> New File. A New File dialog should appear as shown in Figure 2

Add New File dialog

Figure 2

2. Select Cocoa Touch under iOS on the left side and then select UIViewController subclass on the right.
3. Click Next and enter a Class name, I chose SecondViewController. Leave Targed for iPad and With XIB for user interface unchecked as shown in Figure 3

Name View Controller

Figure 3

4. Choose a folder to save new file and click Create button.

Your project navigator should contain similar files as shown in Figure 4

Project Navigator Files

Figure 4

You can see that when the storyboard runtime calls the prepareForSegue:sender: method in the current view controller to prepare it for the segue, the destination view controller has already been initialized in the segue object. Now this is your chance to pass any required data to the destination view controller, SecondViewController.

You can either set the data directly into a property of the destination view controller or pass your data by calling a method on that view controller. Below is the updated code to pass data from the first view controller to the second view controller. Add an import statement at the top of the implementation file of your first view controller to reference the second view controller as shown in Figure 5.

Import Statement

Figure 5

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSLog(@"Source Controller = %@", [segue sourceViewController]);
    NSLog(@"Destination Controller = %@", [segue destinationViewController]);
    NSLog(@"Segue Identifier = %@", [segue identifier]);

    if ([[segue identifier] isEqualToString:@"SimpleSegueToSecondViewController"])
    {
        SecondViewController *viewController = [segue destinationViewController];
        //viewController.dataModel = ...
    }
}


Adding a Storyboard to an Existing Project

If you already have an existing project where you navigate between screens manually and you want to start using storyboards, I will show how to take advantage of them with the below steps. The structure of project apps that use storyboards are different than project apps that do not. For once, the storyboard-based apps no longer use a main nib file for their windows. This needs to be removed from the .plist of our app. Also, when updating an old app to now use storyboards, you will need to make the app understand what storyboard files are by setting them in the .plist.

The last step below mentions to make sure that the app delegate in your app is not messing with how we are intending to load our storyboards. All apps are different, but you have to make sure that the app delegate is not assigning any object to the rootViewController property of the window. If it does, your storyboards will not be displayed and you will spend time trying to find out what the issue is.

1. From the File menu, choose New->New File
2. In the New File dialog, make sure you have selected User Interface under iOS on the left side and select Storyboard on the right.
3. Click Next to move to the next screen.
4. In this screen, pick the Device Family for which you want to create your storyboard. If your app is an iPhone or iPad only app, then pick the appropriate device family. If your app is a universal app, you will need to select one device family now, create the storyboard file and then come back and create another one for your other device family. Then press the Next button.
5. Now select where to save your storyboard file.
6. In the Project Navigator in Xcode, find the *Info.plist file. Note that this *.plist file might have been stored under a different name depending on the name of your project. Once you click on this file, the property list editor will open automatically as shown in Figure 6

Plist Editor

Figure 6

7. If you have any of the following keys, delete them from the *plist file: NSMainNibFile and NSMainNibFile~ipad
8. If you have an iPhone or iPad only app, then create a new key called UIMainStoryboardFile for iPHone or UIMainStoryboardFile~ipad for iPad. If you have a universal app, create both these keys.
9. For the value of these keys, provide the filename of the storyboards that you created without the .storyboard extension.
10. Make sure to save the .plist file.
11. Remove the application:didFinishLaunchingWithOptions: method from your app delegate’s implementation. Usually in this method, you write logic to set up different view controllers and windows and etc. With storyboards, you will no longer need this. At the very least, just remove the logic code in this method if you have any other code inside that remains relevant.

Introduction to iOS 5 Storyboards Part 1

I have been reading an early preview of iOS 5 Programming Cookbook and wanted to show a new feature called Storyboards. In previous versions of iOS, you would use navigation controllers to push and pop view controllers to be shown on the screen. Now in iOS 5, Apple believes this can be done easier with Storyboards. Soryboarding is the new way of defining the connection between different screens in your iOS app. For example, a nightmare before would be if you had 20 unique view controllers which you coded months ago, looking at the source code now you would have to spend time finding your way around the connection between these view controllers and what view controller is pushed when a certain action is taken by the user. This could become very difficult in keeping track on which view controllers are connected if you have not documented your code or created flow charts. Now with Storyboards, you can now view/create your entire app’s UI and the connection between each view controller in one screen using Interface Builder.

With storyboards, one screen’s worth of content is called a scene. A scene on the iPhone can be thought of as the view of a view controller, where you put all yoru contents on the screen to be presented to the user at the same time. On the iPad, more than one scene can be presented to the user at the same time because of the bigger screen. Storyboarding supports transitioning from one scene to another, similar to a navigation controller pushing a view controller on top of another. That is a transition. In order to explain Storyboards we will cover the following topics:

1. Creating a Project with Storyboards
2. Adding a Navigation Controller to a Storyboard
3. Passing Data from One Screen to Another
4. Adding a Storyboard to an Existing Project

Lets begin….

Creating a Project with Storyboards

I’m running the latest bits of Xcode which is v4.2.1 from Nov. 17, 2011 update on the AppStore. It includes many updates including iOS 5 SDK. With this new update, the New Project dialog has changed with new project such as Master-Detail Application, Single View Application, etc as shown in Figure 1.

1. Select Application on the left under iOS and on the right, select Single View Application and click Next button as shown in Figure 1.

New Project dialog

Figure 1

2. Name you project by filling in the Product Name field. I chose StoryboardSample. Also, make sure you check Use Storyboard and click Next button, as shown in Figure 2.

Name Project

Figure 2

3. Choose a folder location to save project and click Create button.

Since I created a project with Use Storyboard and Device Family = Universival, there are *_iPhone.storyboard and *_iPad.storyboard files that were added to the project as shown in Figure 3.

Storyboard Files

Figure 3

Adding a Navigation Controller to a Storyboard

Using the project created from the last section, you want to be able to manage multiple view controllers. In order to do that, you need to set a navigation controller as the initial view controller of your storyboard file. In previous iOS versions, we would create a view controller that would inherit from UINavigationController and set that class as the root view controller.

In order to add a navigation controller, simply follow these steps:

1. Select the iPhone storyboard in the Project Navigator in Xcode. For the StoryboardSample project, the file is MainStoryboard_iPhone.storyboard.

2. Once the storyboard file is selected in IB (Interface Builder), simply double-click on an empty space on the storyboard’s canvas and you will see the content shrink in size and give you more free space to play with, as shown in Figure 4. You can also you can the zoom in/out control in the bottom right of the canvas.

Default IB With View Controller

Figure 4

3. Under the View menu, select Utilities->Show Object Library

4. In the Object Library, find the Navigation Controller object and drag and drop it into the storyboard, to the left side of your existing view controller.

5. The navigation controller we just dragged on to the canvas already comes with a view controller of its own. We do not need this so go ahead and delete this view controller by selecting it first and then pressing the Delete button on the keyboard. Now we are left with only the navigation controller and our original view controller, as shown in Figure 5.

Navigation Controller With View Controller

Figure 5

6. Now we need to hook up the navigation controller with the view controller. Select the navigation controller object on the storyboard. Then, hold down the Control key and left button on your mouse and drag your mouse over to the view controller (on the right) that we had on our storyboard originally. This will draw a line from the navigation controller all the way to the view controller. Now release your mouse button and a Storyboard Segues pop-up will appear. Select Relationship – rootViewController. Now you will see a segue drawn from the navigation controller to the view controller, as shown in Figure 6.

Navigation Controller Connected With View Controller

Figure 6

7. All that is left is to make our navigation controller the initial/root view controller. To make our navigation the initial view controller, simply select the Navigation Controller under the Navigation Controller Scene panel in IB, as shown in Figure 7.

Navigation Controller Scene

Figure 7

8. Next, select the View menu in Xcode and choose View->Show Attributes Inspector. Once the attributes inspector is opened, under the View Controller category, check Is Initial View Controller checkbox, as shown in Figure 8.

Is Initial View Controller Property

Figure 8

Now if you run your application, you will notice that the initial view controller has a navigation bar on top, indication that this view controller now has a navigation controller, as shown in Figure 9.

iPhone Simulator

Right now we have a navigation controller with a view controller inside it. Now we want to trigger an action and then move from one view controller to another. In order to do that, let’s place a button on our view controller and push a view controller into the stack once the user presses the button.

9. Select MainStoryboard_iPhone.storyboard

10. In the Object Library, select View Controller object and drag and drop it onto the right side of our existing view controller on the storyboard, as shown in Figure 9.

Add Second View Controller

Figure 9

11. In Object Library, find the Button object and drag and drop it into the first view controller as shown in Figure 10. Note that if you are zoomed out, Interface Builder will not allow you to drop a button onto a view controller. You need to double click on an empty space on your storyboard to zoom into it before Interface Builder allows you to drop UI components onto your view controllers.

Add Button To View Controller

Figure 10

12. Now select the button, hold down the Control key on your keyboard and then hold down the left mouse button all the way while you drag to the second view controller.
13. Now lift your fingers off the mouse button and the Control key. A Storyboard Segues pop-up will appear. Select Push.

Now if you look at your storyboard, you will see the first view controller is connected to the second view controller.

Run the app and click on the button on the first view controller. You will see the second view controller will automatically get pushed onto the stack of view controllers. Once the second view controller is pressed, you will see a back button on the navigation bar. If you press that button, you will be send back to the first view controller, as shown in Figure 11.

Back Button

Figure 11

In Part 2 of this blog post, we will cover the last two sections: Passing Data From One Screen to Another and Adding A Storyboard To An Existing Project.

iOS 4 Persisting Data

I’m thinking of writing a very simple iOS app that has a login control. So a user can register or login with an existing account. While brain-storming how to approach this, I’ve looked in to SQLite that has been around for the longest time or using from the Cocoa Touch Library that was introduced in iOS 3, Core Data Framework. Currently I’m in the middle of researching the difference between the two. But I started thinking more and obviously I want my repository to be at a central location so multiple devices running my simple login app can access it.

Thus, I’m also looking into setting up a web service, perhaps a WFC service and throw it up on a web service I own. Then write some objective-c in my login app using NSURL, NSURLRequest and NSURLConnection classes. While scouring online, there’s a great SDK by Red Gate company, MobileFoo called iSQL SDK that allows you to retrieve data from a SQL Server at http://www.mobilefoo.com/ProductIndex.aspx. Look forward to a future blog post as I’ll play around with their SDK and see how seamless their wrapper classes allow me to hook up my login sample client app with a SQL Server database that will authenticate a user.

Overview of Stanford Online Class Introduction To Databases

For the last 10 weeks, I’ve been taking the Introduction To Databases class online through Stanford, http://www.db-class.org. I’m just going to write an overview of my experience with the class. The class was taught by Professor Jennifer Widom. She did an excellent job of lecturing us on topics that covered Relational Databases, XML, Relational Algebra, SQL, Relational Design Theory, UML, Indexes, etc at a high level. Her process of video lectures and PowerPoint/PDF slides helped understand the information. She also provided Optional Exercises and resource textbooks to help you prepare for the weekly quizes/exercises and exams.

The QA Forum message board helped a lot to get through the class. It allowed students to socialize and interact on the course material. If you didn’t understand a topic discussed in the video lecture, a student would post a message and in minutes another student would comment or help explain the topic. This helped me solve homework problems I was having trouble finding a solution. Overall, this class was a great introduction to databases. It leaves me wanting to take another class to learn at a lower-level about databases. Plus, the Stanford online class was FREE.

Get Started in iOS Development

Earlier today I presented how to get started in iOS development and compared the code syntax between Objective-C and C#. So far it’s been 2 months since I started learning Xcode and Objective-C. The first few weeks it was difficult and a lot of banging my head trying to understand Objective-C. Now, its slowly becoming second nature and I’m enjoying it more and more making iOS apps.

Once I get a stronger understanding of the foundationg of Objective-C and how to use Xcode, I plan on developing my own iOS app that I’ve had on the back-burner for a few weeks. Stay tune for the details of the app. Also, look forward to more iOS sample apps and my experiences as I learn more and more about iOS development.

For my presentation earlier today, you can grab the slide decks here:
https://s3.amazonaws.com/ZimmerDentalMisc/Overview_iOS_Development2.pptx
You can grab my outline of notes here:
https://s3.amazonaws.com/ZimmerDentalMisc/ObjectiveCandDotNetComparison2.rtf

I will post the sample apps shortly.

The first sample app was a simple Quiz Demo app that showed how to create IBOutlet and Target-Action connections. Also, simple class, method and property declaration. Instatiating NSMutableArrays and adding objets to them. Then looping through the array and assigning the value to a NSString *question variable.

The second sample app was a more realistic app that shows how to hook up a UITableViewController and UINavigationController to a Window. Then population the UITableView with a collection of items from a custom class (Possession). More details to follow.