iPhone to Netbook Porting: Technical Guide

Overview

Having competed with 200,000 other apps in the iPhone App Store for 40 million consumers' attention to your iPhone app you may be looking at ways to broaden your market reach. The Intel AppUp Center has to potential to reach the installed base of 40 million netbook users with a small cross-over to the iPhone market. Through the Intel AppUp® center, you can build Windows or Moblin apps and launch them into the only netbook marketplace out there. Integrating the Intel AppUp® Software Development Kit (SDK) is simple, so the rest of the process of transitioning your app is based on the widely available standard frameworks for Windows and Moblin development.

Table of Contents

Overview

Porting Paths

The user experience

Tool options

Framework comparison

Porting Apps

What makes porting apps hard or easy?

Five Common Porting Paths

Porting Games

Porting Content-rich Apps

Service/UI-heavy iPhone Apps are Recodes

Case Study: weTalkSmack

Getting into AppUp Center



Porting Paths

Depending on when you start to consider cross-platform delivery in your design the way you approach moving from iPhone to Windows may be different. If your iPhone app is already written, mostly in Objective C, then you are likely going want to rewrite it in C++ or C#, as appropriate for porting to Windows. If you have the opportunity to consider cross-platform efficiencies, you might want to create common libraries in C++ so they can be consumed by the iPhone app and Windows. Common content could be created in HTML so that it can be displayed similarly in all environments.

The user experience

When porting an app from iPhone to a netbook, consider the different user experience afforded by each platform. Much like porting to the iPad, netbooks are going to have larger screens to deal with and you will need to scale up for that. This large screen allows a richer interface, so serial tasks such as a list, followed by a details view can be combined into a single view. If you already have an iPad app, then it should can be moved the a Windows netbook platform for directly. You should also look at how your iPhone app uses touch and adapt that for a mouse interface, as most netbooks don't have a touch screen. The major difference will be the lack of gestures (such as pinch-zoom) on most Windows netbooks and that you can add hover-effects when the house pointer is over, but not clicked on, an element. There are other hardware differences and I'll go into these in more detail and provide additional resources in the next article, Beyond the Basics.

Tool options

The majority of Windows development is done with Microsoft Visual Studio. Coming from XCode, you'll find a similar, modern development environment. However, the level of richness depends on how much you want to pay for it. The Express editions of Visual Studio can get you started for free but you'll miss the auto-complete and other productivity features of the Professional edition.

There are other tools available for Windows development including SharpDeveloper and MonoDevelop, but both of these build .NET apps using C# or Visual Basic.NET with no support for C++ so there would be no option for code-reuse.

While Visual Studio Professional is an investment (XCode and tools are free), they are likely worth the money. As Chris Skaggs, CEO of Soma Games, says in his interview on the Intel AppUp center site, "get the real software development tools; the 'free' knockoffs you can download are not worth the headaches."

Visual Studio includes strong support for Intellisense (auto-complete), refactoring, and unit test frameworks. However, you can take it to another level by adding Resharper, from JetBrains, for tightly-integrated, powerful refactoring, templates, and productivity enhancements.

Framework comparison

Clearly moving from iPhone to Windows, you'll be changing languages and I've provided a reference below. However, you also are changing the basic framework for all the system services that you'll be relying on. iPhone uses Apple's Cocoa Touch framework for access to UI controls and graphics, files and storage, and system services like GPS or playing media. Moving to Windows you'll change these to the Windows equivalents.

As a simple example, to play a simple system sound on the iPhone I would write something like this:

iPhone Objective C

#import "AudioToolbox/AudioServices"

@implementation MyViewController

- (void)playSound {
    SystemSoundID soundFileObject;
    AudioServicesCreateSystemSoundID(fileURL, &soundFileObject);
    AudioServicesPlaySystemSound(soundFileObject);
}

To do the same thing for Windows I would write something like this:

Windows C++

#include <msystem.h>

void MyViewController::playSound() {
    PlaySound(fileUrl, NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
}

In the next part, Beyond the Basics I'll dig into a number of platform-specific cases such as media, camera, location and data storage and show comparative examples.

Porting Apps

What makes porting apps hard or easy?

Fortunately, integrating with the Intel AppUp SDK is simple; it basically provides copy protection similar to what Apple applies to your app after you submit it to the App Store. Once you have your app running on Windows, you add one library and as little as five lines of code, test it and submit for validation. This gives your app copy protection through the App Up software and allows your app to be submitted to the store. There are more features in the SDK that you may want to consider, such as start/end tracking for analytics and error reporting - the kind of thing you generally have to manage yourself on other platforms.

Five Common Porting Paths

Getting your app running in Windows will be easy for some cases and hard for others. I'll go into detail on these below, but here are some paths to consider based on your existing technology.

Your iPhone App is: Mostly using iPhone UI and services

To get to Windows: Rewrite in C# and .NET with Windows Presentation Foundation (WPF).

iPhone

Windows

UI

Interface Builder

XAML

Language

Objective C

C#/VB.NET/managed C++

Framework

CocoaTouch

.NET

Your iPhone App is: A C++ core with Objective C UI

To get to Windows: Copy the C++ source, wrap it in managed C++ and consume that from a C+ app under .NET with WPF.

iPhone

Windows

UI

Interface Builder

XAML

Language

Objective C/C++

C#/C++/managed C++

Framework

CocoaTouch

.NET

Your iPhone App is: A significant Objective C core, distinct from your Objective C UI and services.

To get to Windows: Port the core to managed C++ or C# and consume that from a C# app under .NET with WPF.

iPhone

Windows

UI

Interface Builder

XAML

Language

Objective C

C#/VB.NET/Managed C++

Framework

CocoaTouch

.NET

Your iPhone App is: An Objective C game with custom UI using CoreGraphics

To get to Windows: Port the graphics to C++ and DirectDraw, port the rest of the game to C++

iPhone

Windows

UI

CoreGraphics

DirectDraw

Language

Objective C

C++

Framework

CocoaTouch

MFC

Your iPhone App is: An Objective C game with custom UI using OpenGL

To get to Windows: Retain the OpenGL code and port the game to C++

iPhone

Windows

UI

OpenGL

OpenGL

Language

Objective C

C++

Framework

CocoaTouch

MFC

While you are translating your app to a new platform, you should use this as an opportunity to update the app. Take advantage of feedback from your customers, try new features or even consider new architecture.

G - Into the Rain logo

Games like 'G' have a custom UI

Porting Games

Games are often one of the easiest types of applications to translate between platforms because the interface is usually custom (so you don't have to change your interface to meet customer expectations). That said, your release schedule may dictate your approach, as noted in the Intel AppUp center article, " A Tale of Two Ports: A Picard vs. Kirk review of mobile app porting techniques." If you have the ability to plan cross-platform development, as Mike Kasprzak of Sykhronics did, you probably want to consider writing much of your core game logic in C++. This will make it possible to use the same code on iPhone and Windows. Similarly, using OpenGL for graphics means that the graphics can be copied to almost any platform.

On the other hand, as Chris Skaags discovered, moving to a rapid development platform may be a better choice if it means shorter time to market. If you app translates easily into Flash-like functions and graphics you could build it in Adobe Air. This could be very effective for a casual game because the root Flash technology translates to a web-based app and other devices meaning you can immediately use it in other markets.

iEat for Life logo

iEat for Life is a content-rich app

Porting Content-rich Apps

If your apps are mostly about content consumption, as the iEat for Life apps are that we ported to the Intel AppUp Center, you might want to consider hosting the content in HTML with CSS styling and using JavaScript for an interaction. iEat for Life is a series of app with directed dietary suggestions for individuals with particular health conditions such as breast cancer, prostate cancer, heart disease and diabetes. The netbook app that we launched in the AppUp Center hosts an embedded instance if Internet Explorer and loads HTML pages, styles and images from the applications resource file. By building HTML-based rich content we were able to ease the cross-platform with as little Windows-specific code as possible.

Yelp logo

Yelp is a sevice-heavy app

Service/UI-heavy iPhone Apps are Recodes

A common class of apps depend heavily on the iPhone UI and services, contain little custom code and possibly consume a set data set. A good example of these is mobile interface to web-accessed data, such as Yelp. Another example is apps that provide rapid, local access to a set, packaged collection of data. I will go through an example of this below in detail. In this case, it really makes sense to recode from the start. This sounds like a lot of work, but may be less than expected you have already figured out much of the challenge of structure and organization of your code. Now you just have to port those concepts. To get up to speed rapidly and ship quickly your probably want to build this in C# using .NET and possibly WIndows Presentation Foundation (WPF). Using Visual Studio professional or better you can rapidly design and code up your interface. The balance of the work - whether data is a local resource or a remote web call - is then straightforward.

Case Study: weTalkSmack

weTalkSmack is a free iPhone app that gives you a collection of snarky phrases to say for any situation. The first app that the weTalkSmack team released in the AppUp Store is the Golf Edition, with comments and come-backs to throw at your friends whether on the green or at the 19th hole. The bigger vision for weTalkSmack is to provide a series of apps with targeted phrases. This makes an interesting example to port to the netbook because we had to rethink a number of aspects of the app.

The Vision

It seems unlikely that someone will have their netbook with them out on the golf course, so we had to look at this not just as porting code, but also considering and getting new content. For the App Up Center we decided to build weTalkSmack - The Travel Edition. Many people do take their netbooks on trips and there's always someone (hopefully a travel partner) that you can make fun of. So our first step was to gather and collect new phrases and organize them into situations or opportunities: plane, taxi, bus, rail.

The User Experience

weTalkSmack is a typical, simple iPhone app. It uses list views to show a collection of categories ("opportunities") and these lists have a "disclosure" action to reveal detailed data (lists of "smack talk").

iPhone App - Opportunities iPhone App - Insults

When considering the larger screen of a netbook we naturally decided that the opportunities and smack list could easily sit on the same screen, making navigation simpler. So, our next step was to mock up the screen for the netbook.

Mockup of Windows App

The rest of the screens are static content (About, Help and the splash screen) or are embedded web views (Contact Us, More Smack and Submit Smack). The web views we can port to Windows by embedding a WebBrowser control (that runs Internet Explorer).

The Code Design

Looking through the iPhone app it takes advantage of the UI features of the iPhone - table views, static graphic views and web views. There isn't much custom logic in the app, and it is written in Objective C with calls to iPhone's Cocoa Touch framework. The UI is built with Interface Builder configuration files. None of this can be copied to a Windows app directly, so we're by-and-large looking at a rewrite of the code. We want this to be straightforward and quick, so we're going to do this in C# using Windows Presentation Foundation (WPF), and use the .NET library for Intel AppUp center to integrate it into the Intel store. WPF is a relatively new framework from Microsoft that works with Visual Studio 2008 and applications can target .NET 3.0 and later (by default Visual Studio 2008 will target .NET 3.5). WPF allows you to define your view layouts in an XML format (called XAML) that will be familiar (in concept) to programmers who have used ASP.NET.

Code aside, the app does contain a significant amount of data (the categories and phrases) that could be used cross platform. When the team originally built weTalkSmack for iPhone they could have put strings into resource files or even created a resource that could be consume cross-platform. However, they were building the first app and so encapsulating it then would have been speculative and likely a waste of time.

Considering the Windows version, we're changing the platform and the content. While we could create a custom resource so that the content can be used across platforms (so that, say, we can can build the weTalkSmack for iPhone - Travel Edition), we're not there yet, so we chose to keep the data tightly coupled. As it turns out, using an XML data source for the data is easy with WPF and makes sense. So while the data is still bundled in the app, it would be easy to copy it to an iPhone version or pull it from an external file when the project gets to that point.

Creating a Windows Application

To get started I opened Visual Studio and created a new WPF Application project, called "weTalkSmack".

New Project Dialog

Visual Studio created a default project and files that make a basic desktop app window. Under WPF a Window can host a Frame that allows you to navigate multiple Pages.

This will simplify the navigation and make it similar to the iPhone. I am going to make the rest of the views into Pages and use the Frame's Navigate method to switch them. I'll get to that below when we add the menu.

XAML Layout

The Smack Talking Views

The main Page for the app I named SmackPage and included a list for the opportunities and a list for the insults. Using the Grid layout I was able to insert a label above the left-hand list for the phrase "Opportunities". The right-hand list of insults spans both rows.

Windows XAML

<Border Padding="5" Background="#333333">
  <Label VerticalAlignment="Center" Foreground="White" FontWeight="Bold">Opportunities</Label>
</Border>
<ListBox Name="listBoxOpportunities" Grid.Column="0" Grid.Row="1"
  ItemsSource="{Binding Source={StaticResource SmackDataSource}, XPath=opportunity}"
  ItemTemplate="{StaticResource OpportunityTemplate}"
 SelectionChanged="listBoxOpportunities_SelectionChanged">
</ListBox>
<ListBox Grid.RowSpan="2" Name="listBoxInsults" Grid.Column="1"
  ItemsSource="{Binding XPath=insult}"
  ItemTemplate="{StaticResource InsultTemplate}"/>

iPhone Menu

Let's look at the differences here a bit. This is the bulk of the main functionality of the application and it's significantly different on the different platforms. For the iPhone, we have two Interface Builder-generated XIB files that hold the layout for the root view of opportunities and the secondary view of insults. Each of these contains a UITableView similar to the one at right with corresponding controllers derived from UITableViewController.

iPhone Objective C

@interface RootViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource> {
    NSArray *controllers;
    UIToolbar *toolbar;
    SystemSoundID soundID;
    NSArray *insults;
}
@property (nonatomic, retain) NSArray *controllers;
@property (nonatomic, retain) NSArray *insults;

@end

Custom iPhone Table Cell Layout

While the layout in both apps of the opportunities is fairly straightforward, the insults list includes custom styling. For the iPhone app, another XIB file defines a custom view used to render the insults cells on that screen. Code in the controller's tableView numberOfRowsInSection method handles binding the data to the fields in the view.

iPhone Objective C

CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];
if (cell == nil)  {
    NSArray *nib = ];
}

This design makes sense from a business perspective, so I did the same thing for the Windows app. I created a new Page in the solution called WebView.xaml and embedded a WebBrowser control as the sole control hosted in the Page.

Windows XAML

<Page
    x:Class="weTalkSmack.WebView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="weTalkSmack - Travel Edition">
        <WebBrowser x:Name="WebBrowser" />
</Page>

Then in the code-behind I loaded the appropriate web page based on the parameter passed to the constructor. We haven't used this constructor yet, but we will when we create the menu below.

Windows C#

public partial class WebView : Page
{
    public enum WebPage
    {
        ContactUs,
        MoreSmack,
        SubmitSmack
    }
    public WebView( WebPage page )
    {
        InitializeComponent();

        switch( page ) {
            case WebPage.ContactUs:
                WebBrowser.Navigate( new Uri("http://wetalksmack.com/golf/smack/") );
                break;
            case WebPage.MoreSmack:
                WebBrowser.Navigate(new Uri("http://wetalksmack.com/"));
                break;
            case WebPage.SubmitSmack:
                WebBrowser.Navigate(new Uri("http://wetalksmack.com/golf/smack/"));
                break;
            default:
                // TODO: Show an error message / dialog box
                break;
        }
    }
}

Static Views

The final two views, About and Help, are static in the iPhone app - they just display a bitmap as the view.

iPhone Objective C

@interface ImageController : UIViewController
{
    ImageController *childController;
}
@end

- (void)viewDidLoad {
    UIView *contentView = ;
    contentView.backgroundColor = [UIColor grayColor];
    UIImage *background = [UIImage imageNamed: @"help.png"];
    UIImageView *imageView = [[UIImageView alloc] initWithImage: background];
    self.view = imageView;
    [contentView release];
    [super viewDidLoad];
}

Taking the same approach I created two basic pages that each host a single Image. The image Source can be set in the XAML, so I don't really have to code anything for these at this time.

Windows XAML

<Page
    x:Class="weTalkSmack.HelpPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="weTalkSmack - Travel Edition - Help">
    <Image Stretch="Uniform" Source="assets/help.png" />
</Page>

Navigation

As mentioned above, the iPhone application uses a menu screen activated from the info button on the main Opportunity screen's toolbar to navigate to these additional views. In our mockup, we opted to use a menu, which is more familiar to Windows netbook owners. The navigation for the iPhone follows the same pattern as the Opportunities view -- it populates an UITableView subclass and responds to click actions to load the requested view.

For the Windows app, we can easily add a menu to the main window by including the definition in the XAML.

Windows XAML

<Window
    x:Class="weTalkSmack.Main"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="weTalkSmack - Travel Edition" Height="454"
    Width="781">
    <StackPanel Orientation="Vertical">
        <Menu IsMainMenu="True">
            <MenuItem Header="_About" Click="About_Click"/>
            <MenuItem Header="_Help" Click="Help_Click"/>
            <MenuItem Header="_Contact Us" Click="Contact_Click"/>
            <MenuItem Header="_More Smack" Click="More_Click"/>
            <MenuItem Header="_Submit Smack" Click="Submit_Click"/>
        </Menu>
        <Frame x:Name="MainFrame" Source="SmackPage.xaml"/>
    </StackPanel>
</Window>

Then we wire up even handlers for each named click event in the code-behind. In this case, launching the static AboutPage or HelpPage or launching the WebView with the appropriate page URL.

Windows XAML

private void About_Click(object sender, RoutedEventArgs e)
{
    MainFrame.Navigate( new AboutPage() );
}

private void Help_Click(object sender, RoutedEventArgs e)
{
    MainFrame.Navigate(new HelpPage());
}

private void More_Click(object sender, RoutedEventArgs e)
{
MainFrame.Navigate(new WebView(WebView.WebPage.MoreSmack));

iPhone Menu

Next Steps

From a code perspective, we're done. We've re-designed and re-written an iPhone app to make it run on Windows. There are a few steps left to make this ready for the AppUp store. First we should thoroughly test this, clean up any bugs, add icons, graphics and content as needed. We then need to integrate with the Intel AppUp SDK. Because we're building a .NET application, we'll want to download, link and add coded to integrate the AdpService for .NET. Finally, we need to make sure that it's ready for submission to the Intel AppUp center. See the final section of this article, Getting into the AppUp Center for details on packaging and testing your app for validation and release.

Getting into AppUp Center

As I mentioned in the beginning integrating the Intel AppUp SDK is simple. Now that you have a Windows app you need to add a library and a few lines of code. The Intel AppUp SDK library talks to a client running on the netbook (or the ATDS service in your development and test environment) for authorization and reporting.

There are many other articles and blog posts the AppUp center site to help you through this process. Start with the steps in How to Develop and Application. If you are building a .NET app you will need to use the AdpService for .NET library and take a look at the example .NET app.

You should clearly test the application to ensure that it meets validation guidelines and passes the test cases described in the validation process.

Finally, you'll need to package it in a silent MSI installer (see also Silent Installer Demystified), ready for the validation team to approve.

For more complete information about compiler optimizations, see our Optimization Notice.