Monthly Archive for January, 2009

Consider an Analytics Package for Your iPhone App

Launching an app in the App Store is a great achievement, but you’ll be flying blind with just the sales metrics provided by iTunes Connect.

Inevitably, there will be issues you’ll want to track, real-time user metrics, and a broader understanding of the device population that you’re deployed to.

There are a couple of startups tackling this problem, and I definitely suggest you check out their lightweight SDKs and integrate one with your application. There’s a great similarity across what they are all offering — a few logging methods and a web-based dashboard reporting the results. Most even take advantage of CoreLocation to report back the geographic distribution of your user base.

We’ve been using mobclix to accomplish this, and in general, it’s a good offering. All of this is new, so I wouldn’t get too carried away with your expectations, but this begins to fill the void that Apple has so far not addressed.

One of our home dashboards in mobclix:

Mobclix Dashboard

gives us an instant breakdown of how many users on what devices and what their primary means of connection (wifi, carrier, none) is. We’ve chosen not to track their location, though, as this application doesn’t use CoreLocation

So, when planning your rollout, considering the easy integration of one of these offerings:

How to Add Images to the iPhone Simulator

Adding images to the iPhone Simulator Library is important if you want to do extensive testing with the UIImagePickerController and your source type is UIImagePickerControllerSourceTypePhotoLibrary, or you just want your images to be displayed.

The camera is not available on iPod touches, so this is even more applicable if that’s one of your targeted devices.

There’s a good post about this on ofCodeAndMen()

The trick is to drag your image onto the simulator which will launch Safari. Then, just tap and hold the image to save to your Simulator’s library.

Getting UIImage to work with NSCoding encodeWithCoder

Out of the box, UIImage doesn’t support the NSCoding protocol which means it won’t automatically serialize if you stuff these in a dictionary or object and archive (using NSKeyedArchiver for example). The easy solution is to convert this into an NSData object which does support the protocol:

//convert from PNG to NSData, other method available for JPG
NSData *imageData = UIImagePNGRepresentation(imageToArchive);
[self.currentItem setValue:imageData forKey:@"image"];
 
//after the archived object is unarchived, you can retrieve the image like this
NSData *imageData = [currentItem valueForKey:@"image"];
if(imageData){
       UIImage *image = [UIImage imageWithData:imageData];
}

Without doing this, and trying to archive a UIImage will just result in:


-[UIImage encodeWithCoder:]: unrecognized selector sent to instance

Pretty simple. The key is the helper method UIImagePNGRepresentation found in the UIKit Function Reference.

More Than Just Guidelines

The iPhone Human Interface Guidelines are more than just that — it is essential for you to understand them in order to ensure that your app will be approved for sale in the App Store.

From Apple:
“Applications must adhere to the iPhone Human Interface Guidelines as outlined in iPhone SDK Agreement section 3.3.5.”

Consider this important guideline in the Table Views, Text Views, and Web Views section of the iHIG:

“Table views provide feedback when users select list items. Specifically, when an item can be selected, the row containing the item highlights briefly when a user selects it to show that the selection has been received. Then, an immediate action occurs: Either a new view is revealed or the row displays a checkmark to indicate that the item has been selected. The row never remains highlighted, because table views do not display persistent selected state.”



The easy part to miss when implementing your own View Controller is “The row never remains highlighted”.

In your own custom UIViewController subclasses, you’ll want to address this within the

- (void)viewWillAppear:(BOOL)animated UIViewController delegate method.

Given a UITableView member property, theTableView, you can make sure the selected row gets deselected after popping the previous View Controller:

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
 
//deselect any selected rows
NSIndexPath *selectedRowPath = [theTableView indexPathForSelectedRow];
[theTableView deselectRowAtIndexPath:selectedRowPath animated:YES];
...
}



Treat the guidelines as the law of the land, and you and your users will attain App Store nirvana.

Solid, Comprehensive iPhone State-of-the-Market Overview

From the Amazing iPhone site, the team over there has put together a very thorough review of the iPhone market including history, opportunity, and developer requirements current through the end of 2008. Worth a read, especially for developers interested in understanding the emerging smartphone marketplace.

The Amazing iPhone Report