Feb 01

I’m always appreciative of other bloggers and web sites who link to this site, so when I see a new referral URL in the logs, I typically check it out.

This time it turned out to be a well written report about iPhone business opportunities, and iPhoneIncubator.com is mentioned as a good source of information for SDK developers. Thanks for the link Kisky!

You can download the free report at http://theamazingiphone.com/

written by Nick

Jan 27

Have you every been frustrated with the small circular touch area when setting the accessory type of a UITableViewCell to be UITableViewCellAccessoryDisclosureIndicator? Unless you have child fingers, it’s very difficult to select consistently.

Here’s one way to improve the user experience and create the same effect of a larger touch pad like you see on the YouTube application. To do this, you need to implement a custom table view cell. You can either create your own subclass, or you can add subviews to the cell’s contextView. This example shows how to do the latter.

When setting up my UITableViewCells I like to create methods that provide the elements I wish to use to add to the cell’s contentView. Here I am creating a UIButton of type UIButtonTypeDetailDisclosure to be added to each cell in the table. The button possesses an area of 44 x 44 pixels and occupies the right most area of the table view cell that will be 320 pixels wide and 44 pixels tall. Note here that you define a target and action of your own rather than use the callbacks for the accessory type defined in the UITableViewDelegate protocol.

- (UIButton *) getDetailDiscolosureIndicatorForIndexPath: (NSIndexPath *) indexPath 
{
	UIButton *button = [UIButton buttonWithType: UIButtonTypeDetailDisclosure];
	button.frame = CGRectMake(320.0 - 44.0, 0.0, 44.0, 44.0);
	[button addTarget:self action:@selector(detailDiscolosureIndicatorSelected:) forControlEvents:UIControlEventTouchUpInside];
	return button;
}  

The following shows how to add the button to the cell in the cellForRowAtIndexPath method in your table view controller class. As you add subviews to the contentView, be sure your detailed disclosure indicator is rendered on top. Also, ensure you are properly handling the reuse of your cells.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
...
[cell.contentView addSubview: [self getDetailDiscolosureIndicatorForIndexPath: indexPath]];
...
} 

Finally to process the selection event you need the following code:

- (void) detailDiscolosureIndicatorSelected: (UIButton *) sender 
{	
	//
	// Obtain a reference to the selected cell
	//
	UITableViewCell *cell = [self.tableView cellForRowAtIndexPath: [self.tableView indexPathForSelectedRow]];

	//
	// Do something like render a detailed view
	//		
	...
} 

written by Jess \\ tags: , ,

Jan 20

I have a great idea for a new iHouse. This is relovutionary; nobody has every thought of this idea before. Now I just need to pardner with a very solid iHouse builder to make this realty. I come up with the ideas, you bring the expertise!

You must have at least 2+ years of experience with building iHouses, dealing with Mapple’s approval processess and selling on the Hip Store. Please send me all examples of relevant, prior work so that I can try them out for free.

This is a very simple house. For an experienced iHouse developer this project should only take a few days hours to compete. So I’m being extensively generous in offering to share the guaranteed-to-come future profits with you: 50/50.

This iHouse idea is so super extraordinary that you need to be prepared sign tripplicate NADA and non-complete contract.

If you are good and professional I will email you back.

It cracks me up each time I see these messages on Craigslist and other message boards. The above was aggregated from actual posts. A few minor edits were made to protect the innocent. Now back to our regular scheduled program.

written by Nick \\ tags:

Jan 16

plists are wonderful for storing small amounts of semi-structured data when you don’t want the overhead of using a full-blown database. OS X, as you have no doubt noticed, uses plists extensively to store configuration data.

I like to use plists to create configuration driven applications. On the App Store you can find TRIBE and The Green Book. These two application look very different, but they use exactly the same code base. The difference is a couple of plist configuration files. Our client is very happy with this, because they are busy churning out many different titles for the App Store using this method.

Reading a plist file from the application bundle just requires a few lines of code, and some error handling. I like to place that code in a nice convenience method like this:
 

- (id)readPlist:(NSString *)fileName {
   NSData *plistData;
   NSString *error;
   NSPropertyListFormat format;
   id plist;

   NSString *localizedPath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"plist"];
   plistData = [NSData dataWithContentsOfFile:localizedPath]; 

   plist = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
   if (!plist) {
      NSLog(@"Error reading plist from file '%s', error = '%s'", [localizedPath UTF8String], [error UTF8String]);
      [error release];
   }

   return plist;
}

I’m not too fond of using id as return values or parameters to methods. I prefer stronger type checks, so I typically wrap the readPlist method in two methods that return either an array or a dictionary.

- (NSArray *)getArray:(NSString *)fileName {
   return (NSArray *)[self readPlist:fileName];
} 

- (NSDictionary *)getDictionary:(NSString *)fileName {
   return (NSDictionary *)[self readPlist:fileName];
}

Writing to a plist file is not much more difficult:

- (void)writePlist:(id)plist fileName:(NSString *)fileName {
   NSData *xmlData;
   NSString *error; 

   NSString *localizedPath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"plist"];
   xmlData = [NSPropertyListSerialization dataFromPropertyList:plist format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
   if (xmlData) {
      [xmlData writeToFile:localizedPath atomically:YES];
   } else {
      NSLog(@"Error writing plist to file '%s', error = '%s'", [localizedPath UTF8String], [error UTF8String]);
      [error release];
   }
}

Note that writing to a file inside the app bundle is not good if you want your data to stick around after the application is upgraded since the bundle will be overwritten. You can look at the Apple’s SQLite code examples for code snippets on how to copy files out of the bundle before using them.

written by Nick \\ tags: , ,

Jan 01

Push API

The push API that was announced at WWDC ’08, and scheduled to be live in September 2008, will finally debut in 2009.

Side prediction: There will be per-message fees associated with the push service.

MobileMe API

An API that was hinted at during WWDC ’08 to allow programmatic access to your data in MobileMe will be introduced.

I can’t think of a better way to lock in users to the iPhone/Apple world than an API to MobileMe. This will allow iPhone apps to really use and integrate deeply with your calendar and other features of MobileMe.

More APIs

Apple will release more official APIs that allow developers to access more features of the iPhone, e.g. SMS, Bluetooth, video recording, iTunes music, the phone itself.

Much of Apple’s marketing depends on being the purveyor of the coolest gadgets. So Apple cannot afford to see the most innovative mobile apps to be developed only for other competing platforms. 

No Major Hardware Releases

In 2009 there will only be incremental updates to the iPhone platform such as more memory, better camera, better battery, etc.

Developers are just beginning to understand the iPhone and we are starting to see some innovative apps. Fragmenting the platform with new form factors at this point would be bad. Ask any J2ME developer how much fun it is to play the “write once, test everywhere” game.

Better App Store

The organization of the App Store will be vastly improved with more categories, better keyword search, top lists that are not completely tilted towards $0.99 apps.

Reusing the iTunes infrastructure for the App Store was a stroke of genius, and probably necessary to launch the App Store in the given timeline. But now it’s clear that apps and music have diverging characteristics: 

  • You typically don’t search for music to meet a specific need. 
  • Pricing.
  • For music, audiobooks and video, iTunes is just one of many distribution channels.

More App Store Commerce

Apple will introduce more commerce options for the App Store, e.g. subscriptions and separate billing for content.

The proliferation of ebooks as separate apps that clutter up the App Store and your iPhone home screen, could easily be avoided if there was a way to charge for content separately from apps. Add the ability to sell subscriptions or other means for developers to get recurring revenue, and we’ll see some really innovative apps and business models in the App Store.

No Trials

Probably the App Store feature most requested by developers of serious/expensive apps is to allow for free trials. I predict that this wish will not be fulfilled in 2009.

There should not be any major technical reasons preventing free trial versions of apps since FairPlay DRM already supports rentals that expire after a set time. My guess is that it’s a business decision and Apple makes too much money from “regretware”. It would be very interesting to be a fly on the wall at Apple during the discussions of revenue vs. a better quality App Store. Personally I hope I’m wrong in this prediction. 
 

What are your iPhone predictions for 2009?

written by Nick \\ tags:

Dec 12

Among the most popular posts on this blog have been those about UIWebView. (The fact that it’s the #1 search result on Google for the term UIWebView might help. 🙂

Here’s I’d like to revisit the problem of displaying local images in a UIWebView. In this post I presented a little hack to embed small images into the HTML. While this may work in some cases, it’s far from an optimal solution. For example it does not address other types of external files you might want to refer to from your HTML.

Using relative paths or file: paths to refer to images does not work with UIWebView. Instead you have to load the HTML into the view with the correct baseURL: 

NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString baseURL:baseURL];

You can then refer to your images like this:

<img src="myimage.png">

Or from within CSS like this:

background-image: url(loading.gif)

It’s important to note that images inside your application bundle are at the root of the bundle, even if you place them in an Images directory in your project.

 

written by Nick \\ tags: , ,

Nov 26

It’s truly an honor (and a great sales boost!) to be selected as an Apple Staff Favorite.

This is the first in a series of TRIBE apps I developed for Genus.

 

written by Nick

Nov 04

Jeff LaMarche has a post on how to change the name of an application as it appears on the iPhone’s home screen.

Here’s an alternative way to do it using the localization features of OS X:

  1. Create an en.lproj directory if your project doesn’t already have one. 
  2. Inside the en.lproj directory create a file called InfoPlist.strings.
  3. Add this line to the file: “CFBundleDisplayName” = “YourNewAppName”;

 

written by Nick \\ tags: ,

Oct 31

Debugging tips for Objective-C programming

Great debugging tips from Matt Gallagher.

Demystifying CGAffineTransform

Jeff LaMarche does a great job explaining affine transforms.

Adventures in Cocotron

This is intriguing: Write a Cocoa app, add Cocotron, stir, and out comes a Windows version. Several projects require an application on the desktop computer to interact with the iPhone. I’ve always hesitated to embark on this due to the hassle of maintaining multiple code bases. This might just be the ticket.

Site helps devs monitor App Store ratings across the globe

Once you have your app in the App Store you want to check on reviews and ratings in other App Stores around the world.

Stanford Course CS193P is free online

Want to learn iPhone programming at Stanford? The goal of CS193P is to teach you how to write object-oriented applications for iPhone and iPod touch, using the Cocoa Touch framework on Mac OS X. Download the complete course material here.

 

written by Nick

Oct 24

Timely UI Updates

Getting the iPhone UI to update when you want it to is hard. Erica Sadun presents several good tips.

3D Transformations on iPhone with Core Animation

3D graphics on the iPhone is fun. Bill Dudney provides some useful code examples.

iPhone “Optimized” PNGs

Have you ever examined an iPhone .app file? You can view the contents of most files in the app bundle, except PNG images. This article explains why.

Creating a Full-Screen Camera Preview

An interesting trick to modify the camera preview screen. By the queen of iPhone SDK hacking: Erica Sadun.

Scroll Views

UIScrollView is one of the most frustrating classes in the SDK due to the lack of control you can impose on it. I’m glad I’m not the only one who’s stumped.

written by Nick \\ tags: ,