Thursday, October 09, 2008

Refined the iTimeZone 1.1 Splash Screen

After I posted On iPhone Splash Screens, I started thinking that I should tweak the iTimeZone 1.1 splash screen just a bit. In 1.1 Beta 2, I have the map in the area that alternates between the map and the table view. The table view is going to be what users see well over 90% of the time, so I thought I was giving users the wrong idea by including the map on the splash screen, so I took it out. In 1.1 Release Candidate 1, I also added the copyright notice on the bottom toolbar. The iTimeZone splash screen is a bit of a hybrid, with some Twitterrific like splash elements (app name, copyright notice), as well as the UI elements that will be visible at launch, but I think it's now just the right mix between the two.

1.01.1 Beta 21.1 Release Candidate 1

One more point. I created the copyright text using Acorn. To get the shadow to look like the iTimeZone already in the image which was rendered on the iPhone, I used the following settings

On iPhone Splash Screens

Craig Hockenberry posted today about why Twitteriffic for iPhone/iPod touch uses a splash screen. I have considered the splash screen a number of times for iTimeZone 1.1, but ultimately decided to continue to include a screenshot of the app to make it appear like its starting fast. I actually added more to Default.png so that the illusion is perhaps better, here is the 1.0 to 1.1 side by side:

1.01.1

But it would be so much better if, as Craig suggest, the iPhone OS would save a PNG whenever asked, then load that instead. I don't think this is really voodoo, or something hard for Apple to do. Seems like the logic is just this easy:

  1. If Default.png exists in user's application document folder (i.e. the NSDocumentDirectory of NSUserDomainMask) load it
  2. Else, load Default.png from the bundle root
  3. No step 3
Should be a new option in Info.plist that can be set to automatically have iPhone OS create the user Default.png at application shutdown, or the app can do that itself if desired.

I spun up a quick sample project to test if this was already implemented in iPhone OS 2.1 undocumented, but it doesn't appear to be unless I stuck the user Default.png in the wrong spot. I used the same method from iTimeZone 1.1 to copy a user writable SQLite database, which itself was pretty much straight out of Apple's SQLite Books Sample, to copy a Default.png into the application specific user document folder:

- (void)createUserDefaultPNGIfNeeded {
// First, test for existence.
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableUserDefaultPath = [documentsDirectory stringByAppendingPathComponent:@"Default.png"];
success = [fileManager fileExistsAtPath:writableUserDefaultPath];

if (success) return;
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultUserDefaultPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Default-users.png"];

success = [fileManager copyItemAtPath:defaultUserDefaultPath toPath:writableUserDefaultPath error:&error];
if (!success) {
NSAssert1(0, @"Failed to create user Default.png file with message '%@'.", [error localizedDescription]);
}
}

The variables at runtime look like this:

It doesn't work. If I change NSDocumentDirectory to NSApplicationSupportDirectory, I actually get an NSException that No such file or directory exists.. I didn't walk through the paths to figure out which one, Library or Application Support are not there, I suspect both. Here are my variables using NSApplicationSupportDirectory:

So I created the whole path doing this [fileManager createDirectoryAtPath:documentsDirectory attributes:nil]; and was then able to put a Default.png in the NSApplicationSupportDirectory. Still, iPhone OS did not load the user's Default.png instead of the bundle's Default.png.

Tuesday, October 07, 2008

Tip: Configuring your target in Xcode to open a XIB on launch

If you started your iPhone development without the nice templates in the shipping Xcode, or something just goes wrong, and your XIB won't launch anymore, you might want to check that the Properties of your Target has the Main Nib File filled out, like this:

Using LIKE statement in SQLite 3 from Objective-C

If you aren't that familiar with SQLite 3 and are wondering how to construct statements with the LIKE operator and use NSStrings when you bind to a prepared statement, read on.

Whether you are familiar with Microsoft T-SQL or another variant of the Structured Query Language(SQL), you are probably familiar with a statement like the following:
SELECT * FROM cities WHERE name LIKE 'new%' OR alternateNames LIKE '%new%' ORDER BY population DESC

Now if you want to execute that statement from a Cocoa Touch app running on an iPhone or iPod touch, you have to sort out each of the following:

  • How can the LIKE terms be parameterized?
  • Do I have to escape the NSString in single quotes?
  • How do I put the % symbol in the string?

This may not be the only, easiest, or best way, but it is the one I am using in iTimeZone 1.1.

First, this is how the statement has to be constructed for parameterization:
SELECT * FROM cities WHERE name LIKE ?001 OR alternateNames LIKE ?002 ORDER BY population DESC

Notice that the parameter tokens, ?001 and ?002 do not have quotes around them. This statement needs to be prepared in the usual way.

Next, you have to create new strings that put the % wildcard character into what you are actually looking for:

NSString *wildcardSearch = [NSString stringWithFormat:@"%@%%", cityName];
NSString *wildcardAlternateSearch = [NSString stringWithFormat:@"%%%@%%", cityName];

Notice the %% characters in the format string. This results in one % in the output string. %@ is the replacement token for your string parameter.

Finally, you have to bind your strings to the prepared statement like this:

sqlite3_bind_text(findTimeZone_statement, 1, [wildcardSearch UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(findTimeZone_statement, 2, [wildcardAlternateSearch UTF8String], -1, SQLITE_STATIC);

The parameters are:

  1. The prepared statement
  2. The variable number to bind to
  3. The variable data
  4. The string length. -1 means determine length from the string input
  5. The kind of variable, determining if the API makes a copy of the variable or not. SQLITE_STATIC does not, SQLITE_TRANSIENT does

That is how I have solved the problem. Hope it helps you out.

Even dumber than Microsoft Points, Nintendo Points are Wii or DSi specific

Joystiq posted Nintendo points don't transfer between Wii, DSi which included the following image:

Joystiq credits Siliconera with the original report, which credits Nintendo with the image. Turns out it comes from Nintendo's Fall 2008 Conference Keynote Presentation, which you can watch from Nintendo's japanese site.

Can't wait for Nintendo to innovate more on points schemes and lock them to a console per month, or they evaporate in a puff of smoke.

Received my first donation yesterday

Ironic, a few days after I removed the donations button off the main page, I received my first one, for $0.01 USD.

Friday, October 03, 2008

iTimeZone 1.1: Coming Soon With Updated Icon, and a Retrospective

iTimeZone 1.1 is feature complete and coming soon. One of the things I wanted to improve was the icon. When iTimeZone 1.0 shipped, I was perfectly happy with the icon, but also nervous if it would be up to snuff with the other App Store competition. There are great, good, mediocre, and terrible icons for apps on the App Store. I think the iTimeZone icon already belonged in the good category, and the changes I made to me only solidified that assessment, but if you disagree don't be shy to post a comment. That said, once the rush to release 1.0 faded and I had time to reflect, some things started to bother me about it.

Design
The icon design that I finally settled on as seen in iTimeZone 1.0 and 1.1 had to have these elements:

  • World Map Background. The first public iTimeZone icon only had various clocks on it, a more traditional representation of world clocks. It seemed to me the easiest way to say world clock was to show an image of the world.
  • Clock Face/Target. I didn't just want to convey that this is a world clock application, I want to show that this application shows you where the time is at this point on the map. That's why I distilled the analog clock down to just the markers for the 4 quarters of the clock face, it conveniently visually looks very similar to the iPhone's locate icon in the Maps application. Somewhat ironically, I am not using the location features in iTimeZone, yet...
  • Clock Arms and Anchor Dot. The dot under which the arms intersect is like a bullseye under the clock face/target. The arms need to be there to clearly show you are looking at a clock.

iTimeZone 1.0 Icon
The iTimeZone icon everyone sees on the iPhone or iPod touch is a 57x57 PNG (pictured right). You can either choose to allow the iPhone OS to composite a plastic layer on top and round the corners, which results in your icon being lighter on top than it is on the bottom, or do it yourself. I just let the iPhone OS do it since that is much easier for me. This became issue one for me, the gray just ended up being to washed out. Second, I realized that I could easily tweak the color scheme just a little and maintain (well I guess really establish) that this was a Tangerine Element icon.

iTimeZone 1.1 Icon
Changing the clock face/target to black and removing some shadowing shows up much better on the iPhone, and also black of course is one of the core Tangerine Element colors. The new arm colors are straight out of the Tangerine Element logo, and provide a nicer contrast to the teal continents. The arms are also slightly repositioned so that all quarter markers of the clock face/target are visible and distinct. Further, the arms are as completely in the whitespace between landmasses as possible, allowing more teal to come through. Also, the teal is brighter, so that the plastic composite washes it out a tad less. In other words, it "pops" a bit more.

First Public iTimeZone Icon

Other Discarded Ideas

Thursday, October 02, 2008

iTimeZone 1.1: Feature Complete

iTimeZone 1.0 was released on July 11, 2008 alongside Apple's App Store. We started work almost immediately on iTimeZone 1.1, with the main goal being to greatly expand the city list. It has taken far longer to get to this point, almost as long as 1.0 development, but iTimeZone 1.1 is finally feature complete! Here's what we at Tangerine Element have been working on.

21,072 Cities
There were a little over 100 cities in iTimeZone 1.0. The new list doesn't require network access, just like iTimeZone 1.0 didn't, its all included in the application. Developing the infrastructure to make the new city list work took far longer than I thought. Now that the SDK NDA is lifted for released iPhone OS version, the trials and tribulations warrants its own post.

Revamped UI
The User Interface of iTimeZone has been overhauled in just about every way, but I think it's clearly still iTimeZone. Here are the 1.0 and 1.1 screens side by side and notes on all the changes for made in 1.1.

 1.01.1Changes in 1.1
Main with Cities
  • Added toolbar and moved + and Edit buttons. Had to do this to make room for some new stuff, and future stuff :-)
  • Now. Resets the dials to, well, the current instant
  • i button. Shows the new about screen
  • Added detail disclosure button to city. Done to implement standard way to get to city detail
  • Moved sun/moon icon to center. Had to be done to accommodate detail disclosure button
  • Shrunk the city cell height. With the new toolbar, had to reclaim some space so that it was still obvious there was a row below the toolbar
Main Empty
  • Double-tappable Map Image. Double tapping on the map brings you to the Add City screen.
Add Empty
  • Removed the browsable list. With the number of cities, first attempt at a browsable navigation model didn't work out to well. It may yet return though...
  • Changed navigation model so your top city can always be seen
Add Search
  • Country Flags. Adds a little pizzaz and makes the city you are looking for easier to spot
  • Detail Disclosure Button. See some details about a city before adding it
  • State and Country. Put as much info in the cell as possible without customizing
Main Edit
  • Actually this view hasn't changed much
City Detail N/A
  • Tap the Maps icon. Launches Google Maps on that city.
AboutN/A
  • Tap the iTimeZone icon to open Safari on the product page
  • Tap the Tangerine Element to open Safari on the company site
  • Tap either of the link buttons for the sources of some content in the application

What's Next
We just started a private iTimeZone 1.1 Beta. We will go with the flow of feedback as it comes in, but hopefully it won't be too long before the update is published through the App Store. Even if you aren't in the beta right now, feel free to post feedback in the comments, and thanks if you do.

Wednesday, October 01, 2008

Apple lifts the iPhone SDK NDA

Right now on the Apple iPhone Developer Portal is the following greeting:
We have decided to drop the non-disclosure agreement (NDA) for released iPhone software. We put the NDA in place because the iPhone OS includes many Apple inventions and innovations that we would like to protect, so that others don’t steal our work. It has happened before. While we have filed for hundreds of patents on iPhone technology, the NDA added yet another level of protection. We put it in place as one more way to help protect the iPhone from being ripped off by others. However, the NDA has created too much of a burden on developers, authors and others interested in helping further the iPhone’s success, so we are dropping it for released software. Developers will receive a new agreement without an NDA covering released software within a week or so. Please note that unreleased software and features will remain under NDA until they are released. Thanks to everyone who provided us constructive feedback on this matter.

That is a pretty large weight off my shoulders. The NDA has had a silencing effect which was obviously not helpful to the long term growth and stability of the iPhone OS platform.

Somehow I don't think Google has lost 1,184.60 today

Stocks.app sure looks broken...