Thursday, December 18, 2008

Tip: Install SmartSleep for OS X

Brent Simmons, maker of the excellent NewNewsWire, linked to Mike D's Virtualization Blog for manually configured how Intel Macs go to sleep, specifically changed the default (suspend to RAM + hibernate to disk) to the old PowerPC based Macs style (suspend to RAM), aka Fast Sleep. Brent then linked to SmartSleep, which is a preference pane that puts a GUI around configured the sleep options that were previously only available in Terminal, and implements SmartSleep. This setting configures OS X to use suspend to RAM when the battery has a strong charge, and turns on hibernate when it drops below a threshold. Sweet!

If you are positive you don't want to use hibernate, you can disable it and then get some disk space back (file size matches much RAM you have installed back).

  1. Close System Preferences
  2. Open Terminal
  3. Type cd /var/vm
  4. Type sudo rm sleepimage

Thursday, December 11, 2008

Friday, November 28, 2008

iTimeZone is on sale for Black Friday

iTimeZone has been discounted to $0.99 to commemorate Black Friday in the US in the App Store in iTunes. Extremely curious if I can "make it up in volume", the 50% reduction in sales price and revenue.

Tuesday, November 11, 2008

iTimeZone on iTunes App Store Front Page

As I usually do, I logon to to the iTunes Store on Tuesday and check to see what new content is available. I happened to do this last night after midnight right before I went to bed. Imagine my utter shock to see iTimeZone in the NEW section on top of the App Store home page. Here is a screenshot for posterity's sake:


click for larger view

Real estate is even more precious on the App Store app on the iPhone and iPod touch, but iTimeZone also managed to make it to the top of the list. Here are two images, one the default loaded, the the second slightly scrolled to show the iTimeZone row completely:

Why Now, What's Changed?
I have no idea why iTimeZone has been granted pretty prominent placement in the NEW section on the App Store home page now. iTimeZone 1.0 was released when the App Store opened, iTimeZone 1.1 was released on October 21, 2008, and iTimeZone 1.1.1 (small bug fixes) was released on October 30, 2008. I have not been contacted by Apple, but if anyone from Apple is reading this and you can comment, I would love to hear why (dave dot murdock at mac dot com). It is entirely possible this is an accident, but I think that unlikely. Each of those tiles on the any of the iTunes Store home pages (Movies, TV Shows, App Store) is premium real estate and clearly under editorial control. I think iTimeZone's promotional position on the App Store will last a week and I am hopeful it will accelerate sales. Thanks Apple!

Friday, October 24, 2008

Using the built-in OS X Grammar Checker with Mail.app

I am no spelling whiz or grammar genius, so I rely heavily on software tools like Microsoft Word and OS X's built-in system wide spelling and grammar checking. Word I believe was the first to implement spelling and grammar checking as you type, for me it was a huge innovation. OS X's built-in spell check nearly anywhere you type text, especially on the Web in Safari, was one of those extremely nice surprises coming from Windows years ago. It is one of those "why isn't this in Windows" features.

Mac OS X 10.5 Leopard added English Grammar checking as you type. When I saw this on the Leopard Feature List (pictured left), I was extremely excited about having a system wide grammar checker. I was really looking forward to having this functionality in Mail.app, problem was, I am embarrassed to admit I couldn't figure out how to use it. But I figured it out now, here's what I am talking about.

Turn it on
Grammar check is supposed to be on by default as you type, but it seems to depend on the app. If you want to make sure it's on, you have to right click in a box you enter text, then click on Spelling and Grammar, then finally make sure Check Grammar With Spelling is checked.

Make Mistakes, Get Suggestions
Here is a sample sentence that the OS X Grammar checker flags:

I had always expected that you should right-click on any of the words with the green underline to see grammar suggestions, just like in Microsoft Word. In Mail.app, this isn't what happens. When you right-click in Mail, you see the menu on the left without suggestions. When Leopard first shipped, I thought this surely must be just a bug and kinda forgot about it. Then today something unexpected happened. I hovered over the grammar text by accident, which you then get to see a tooltip like this:

So you can use the tooltip, but I also found that their is a floating Spelling and Grammar tool window:

But What If Mail.app Is Broken in 10.5.0 - 10.5.5
Seeing the tooltip I thought Mail.app's behavior must be by design, but after playing around some more, I don't think that is the case. I use MarsEdit to write my blog posts, and since it's a Mac OS X app, the place where I type my content is the same OS X text area that does automatic spell checking. I didn't remember ever seeing grammar checking while typing, so I went and turned that on and typed my sample sentence:
Bob said better to be feared than respected, with regards to investing in stocks.
Sure enough, with regards to was highlighted as having faulty grammar. I right-click, and there are suggestions on the right-click menu as pictured on the left! Tough to draw a conclusion, Mail could intentionally (by design) or unintentionally (bug) not be showing grammar suggestions on the right-click menu. I filed a bug on it, #6319745 in RadarWeb (and I hope Radar, but I don't have access to the actual app).

iTimeZone 1.1 Released to the App Store

On Tuesday October 21, 2008, iTimeZone 1.1 was released to iTunes App Store. This was actually a shock, since I had been reading from other iPhone developers that approval times where somewhere between 1-2 weeks. iTimeZone 1.1 was approved in 33 hours! This was such a surprise, that I hadn't done anything on the Tangerine Element site to document the release. I was scrambling around on Wednesday in my spare time to get it done, and it took me a bit of discovery to use the Apple approved App Store logo (seen left) instead of the App Store iPhone icon I was using since launch.

As for what new or different in iTimeZone 1.1, you can visit the product page or other posts on the blog:

Thursday, October 16, 2008

Video game saving is broken, the content is the gamers, and how to fix it

Save Game Info I have never designed a video game, but I have been playing games for a long time. Being a software developer, I have some strong opinions on software design, and game design in particular lately. Specifically, I think the way saving works in games has to fundamentally change. Developers have to rethink how their save systems work, and consumers deserve clear upfront information about how they can use any games' save system. Why is this important? Because knowing upfront the information about the save system can directly affect whether you enjoy the game, whether you can finish it, and whether you can access all the content. The handful of recent titles that drove me to think this through were Metroid Prime 3: Corruption on the Wii, Rock Band 2 on the Xbox 360, Half-Life 2 on the Xbox 360, and Star Wars: The Force Unleashed on the Wii.

What is a saved game?
Wikipedia defines a saved game as:

A saved game is a piece of digitally stored information about the progress of a player in a computer or video game. This saved game can be reloaded later, so the player can continue where he or she had stopped. Players usually save games to prevent the loss of progress in the game (as might happen after a game over unless the game features permadeath, in which the save file is permanently deleted), especially when interrupting or ending a game session.

While that is a perfectly serviceable definition, a saved game is really a piece of the gamers' life. A saved game then allows the gamer to retain a portion of their life that they have chosen to share with you game designer by proxy through the game. Notice I didn't say "your game" to game designers. That's because once you release the product to the public, it is now a shared creation, because the game is nothing without an audience. But a saved game is also more than that, it is the gamer's key to the content which they have already bought! Video games have been using digital rights management (DRM) for years, and no one has been talking about it. Not only to protect a game disc from being copyable, but nearly all games disallow access to all their content unless the gamer has played through the game nearly exactly as the game designer said the gamer should. If the game doesn't allow gamers to save their progress at will and provide access to all content once bought, the game is broken because you game designer aren't valuing the gamers' time, and thus their life. Sorry if that sounds too dramatic, and I know it's only entertainment, but I can't think of another way to spin it.

A word about the kind of games
I am really only concerned with home video games where the gamer is involved with either a single-player or co-op experience. Traditional multiplayer or MMOs aren't addressed with this post because as a shared public experience, there is intentionally and intrinsically, the decision by each individual gamer to participate in that kind of experience. That said, I do over one piece of advice in the solution section for MMOs.

Time is all we have
Time is the most precious commodity any person has. When you engage with any form of entertainment, you want to know if it's worth your time. To make that judgement, you seek out reviews and opinions from people you trust. If you decide that something is worth your time, video games, as far as I can tell, are the only popular mass entertainment form where the consumer isn't in control of the content and the time required to finish the product is open ended. There is no information at the time of purchase, not even an estimate, about how much time it's going to take to finish the game. Movies have running times and the viewer can skip chapters or fast forward and rewind. Songs have length, fast forward and rewind. Books have pages that the reader can randomly turn to. Even sports have a match time limit or set number of points. Concerts have expected length. Games, nothing. You literally have no idea what you are getting yourself into. How can we be 30+ years into home video game systems and still not have such a basic piece of information, duration, easily communicated to consumers? How can gamers still not be allowed to choose what parts of the game to play or not?

What's wrong with save game design?
Simply, the gamer is not in control of the experience. It seems game designers have gone to great lengths to not allow users to have control over the game since there are actually numerous different kinds of save systems employed in modern video games. I am not presuming this is an exhaustive list, but in my experience:

  • Save Anytime. User can choose to save whenever they want, and that exact moment in the game is exactly where they return if they load that save game. There are actually a couple sub-variants on this.
    • Limited to a fixed number. Either through design or technical reasons (i.e. available memory)
    • Unlimited. User can save as much as they like up to the limits of storage
  • Checkpoints. At fixed points in the game, user progress is automatically saved. There are also sub-variants on this kind of save game system.
    • Checkpoints can only be returned to within a level. Once you hit a checkpoint, if the character dies between checkpoints, you return to the previously saved checkpoint. If you turn off the game, you return to the beginning of the level unless the user can also choose to save wherever they want. Another anti-feature to this system is that the current checkpoint replaces the last checkpoint. This is bad because if something is broken in your current checkpoint (e.g. You are stuck on the side of a cliff you can't climb *cough* Halo 3 Highway level) then you can't step back a checkpoint, you have to restart the whole level.
    • Checkpoints can be returned to on game load. Nicer, since intra-game sessions are not snapped to level.
  • Saving embedded in the game world. This is perhaps the worst save system because the game designer doles out the required resource with extreme scarcity. Worse, it makes no sense that a save mechanic is embedded in the game. It would be like you could only pause a movie at certain scenes in movies on DVD, which of course sounds insane.
    • Tokens. If you have ever played a Resident Evil game with its typewriter ribbons, you know what I am talking about.
    • In Game Save Stations. In Metroid Prime 3: Corruption the only chance for a user to save is at certain places in the game (sorry, can't remember the name)
Why are these save systems, excluding Save Anytime - Unlimited, in use today? Here are the reasons I have come up with:
  • Lack of confidence. I can't help but think game designers, perhaps due to the immaturity of the form, in someway fear that players won't want to play their game unless they are in some way artificially induced to progress.
  • Inability to save as a dramatic device. Game designers rely on the inability of the gamer to save progress to create tension. This is bad idea. The tension should come from the story.
  • Game challenge tied to limited save availability. I can hear the argument coming. If you give gamers the ability to save anywhere, what's left of the game? It is way past time to do away with this outdated thinking. For example, in Star Wars: The Force Unleashed, if I could save anywhere, it certainly wouldn't have prevented me from playing through the game. About the only thing it would have done is cut down my artificially inflated play time by about 15 minutes.
  • Masochism. I don't know if gamers or game designers, or both, have enjoyed this abusive relationship, perhaps so, but I for one have had enough. I have stopped playing games that don't respect my time. The reason why Half-Life 2 triggered my thoughts on this is because it's one of the better ones in recent memory allowing you to save whenever. It automatically saves at certain times, but you are limited to a certain number of chosen saves. Also, you don't really get enough information about the save on the load screen.

Solution: Saving is entirely at user discretion and should be a platform feature
This is the way saves should work:

  • Gamers should be able to save anytime, anywhere, as many times as they want. Game designers can continue to structure their games as a series of challenges, but it is up to the gamer to decide if they want to play through the challenges as designed.
  • Saving can be disabled during challenges, but they can't last longer than 15 minutes. A challenge is an uninterruptible task, liking fighting a boss. But at whatever difficulty level you are playing at, those encounters can't last longer than a set period of time. Based on my experience, 15 minutes is the mark. Any more than that, and it's no longer a fun challenge, it becomes a job.
  • Games should have the equivalent of chapter selection on Movies.The user should be able to randomly access any part of the game they want, even without having played through the game. Again, it's up to the user to decide if they want to play the whole game, or if they just want to show their friends a part of the game without local save files.
  • All game controllers should have a Save button. Seriously, 2008, and there is not a uniform way to trigger either a save game screen, or ideally a "Quick Save" option. Also, why not normalize some buttons with DVD+DVR controls? The "start" button on the Xbox 360 should just be labeled a play/pause button. The back button could easily be replaced with a Quick Save button.
  • Game system should standardize the UI for save games. No developer should have to spend time writing their own save systems. It would be like having to write the code for DVD player pause/play functionality every time you release a movie, insane.
  • Save games should be backed up by the platform (e.g. Xbox Live, Playstation Network) and synched to your other consoles No reason I shouldn't be able to start playing a game on the console under my big screen TV, make progress on it at a friends house, and then finish it at home again.
  • Access to game content in multiplayer modes should not be tied to progress/completion of single player content. I can't tell you how many now I buy a new game to play the multiplayer parts first, only to find it's crippled because I haven't played the single player part. Mario Kart Wii, Star Wars: The Force Unleashed Wii, Rock Band 2, the list goes on and on. And sorry, unlock codes are lame, a relic of a bygone era. If the industry wants to grow up, it has to stop doing this. Also, unlocking content is not a re
  • Save game files should contain information about the game at the point in time, so the gamer understands where in the game they are. Actual thumbnails from the game when you save are a must. More detailed information too, like any meters you can see on screen, you should be able to see the data about that in the save.
  • Games need to auto-reload to last save on launch. What happens when you watch a movie and turn off your DVD player, or watch a video in iTunes, then stop it and start playing again? It resumes from where you left off. All games should default to this! If this isn't the 90% case when playing through a single player game, I don't know what is. But this load also needs to be cancelable on the chance that its wrong. The current way most games work is just dumb. On Xbox 360, you have to:
    1. Start the game
    2. Click a button to get past the obligatory landing screen after the parade of logos
    3. Select Load Game and press button
    4. Select where you save game is stored
    5. Figure out which save game you want to load
    6. Wait for load
    Loading the last user saved or system saved game should be the default in all games until the user quits the game in a different mode (e.g. multiplayer), which it should then launch into.
  • Stop showing most publisher/studio/tech logos on launch. Take a cue from the iPhone, when the user or game saves progress, take a full screen snapshot of where in the game the player is. When the game is reloaded at launch, show that screenshot with a progress meter if its a long load, or just get the game running and make the content animated from that screenshot frame. You can even composite unobtrusive logos in a letterbox like fashion over top of the saved game screenshot. Animated logos with surround sound are only cute once, then despised every time after through the appearance of blocking the gamer from getting back into the actual game. I don't need to see the Havok logo anymore in a game, I get it. The equivalent would be like having to see that the filmmakers used Panavision or Kodak before the movie even starts, silly. Doesn't everyone hate having to sit through the FBI warning? That's one of the sweet things about movies from iTunes, no FBI warnings, trailers, or multiple studio banners, one on the film and one for the home video division. If you have to pay a few more dollars to get the engine credit to the end credits, please do so.
  • For MMOs with challenges (e.g. Raids/Dungeons) dependent on a group, use game telemetry to provide probable time estimates. I have done my fair share of raiding in World of WarCraft. I was never able to do a lot of raiding because I never had a good idea how much time any raid or dungeon run was going to take. WoW collects a tremendous amount of data about the game, which I call telemetry, and it should be used to provide gamers estimates based on past raiding/dungeon parties similar to your own.

Wrap-up
I am sure I have missed something, or there are holes in some of my arguments. This post was already long enough, covering every possible corner case would have made it ridiculously longer. I am more than happy to answer any comments, or if you want to send me an email you can through innerexception AT mac.com

Wednesday, October 15, 2008

iPhone app version and build numbers

I think every iPhone developer should know how to assign version and build numbers to their app. If you have come from another platform, like I have, the Apple way is the same but different. I am standing on the shoulders of Chris Hansen for a lot of this post. His post on Xcode: Build numbers and versioning with agvtool was the starting place for me on a lot of this information. Chris' post is nearly 3 years old now, Apple has moved some stuff around and it isn't iPhone specific. Plus, there are no screenshots :-)

Marketing or Build Version?
Apple's iPhone application templates create an Info.plist in the Resources group for you that is configured like this:

Highlighted is the Bundle version with a default value of 1.0. This was exactly how iTimeZone 1.0 was configured. For iTimeZone 1.1, I wanted to be able to show both the marketing version (Version 1.1) and the build number (Build 14), and toggle between them in the app, since I was going to distribute the app to beta testers. So i thought Bundle version was the marketing version because the templates fill it out with 1.0, but that is not the whole truth. Since the iPhone app templates don't really do anything with Bundle version, you have to look at a Cocoa OS X sample application to see the right behavior.

When you only have Bundle version, in a Cocoa OS X app you see a built-in About box that looks like this:

When you add a new key to Info.plist called Bundle version string, short, and flip your 1.0 into that key, and then put something more traditionally resembling a build number (14) back into Bundle version, the Cocoa OS X built-in About box looks like this:

So which keys you should use on the iPhone are pretty clear, Bundle version is really your build number key, and Bundle version string, short is really your marketing version. Now lets build something.

Build It
Whenever you hit Command-B in Xcode, you are creating a build. As a developer you are building all day long. But a developer build and a build you intend for distribution are two different things. When a build is distributed, you need to assign it a unique identifier so you can ask people what version they are on or for bug reporting purposes at a minimum. This is usually referred to as the build number. I am not talking about continuous integration here, only the manual process, but if you wanted to setup continuous integration, you just need to automate what I talking about.

Apple has a tool, called agvtool, to increment build numbers, the Bundle version in your Info.plist, as well as make that number a variable in your code. The tool is called agvtool for Apple-generic versioning tool for Xcode projects. In order for it to be usable, you have to change a few build settings in the Versioning section for All Configurations. Here is the screenshot of iTimeZone 1.1:

The key setting is Versioning System. This must be set to apple-generic. I don't know of any other possible setting except None. This does not mean that Xcode now automatically increments a build number for you, you have to take specific action to get the build number incremented. Now that those are set, you have to close your project, open Terminal, and do the following to increment your build number:
/Developer/usr/bin/agvtool next-version -all

This was one of differences with Chris Hansen's post, Apple moved the location of the tool. Also, I encourage you to hit man agvtool for all the options, like automatic check-ins to source control on running agvtool, but I haven't set those up yet. Now you have pretty much everything you need to use the build number system, but you need to be able to use this information in your iPhone app.

Using Build and Version Numbers In Your iPhone App
Unfortunately, there really isn't at the time of this writing a defined pattern for displaying version numbers or build numbers in iPhone applications. In iTimeZone 1.1, I choose to put a dedicated About screen into the app. Not only to show version and build numbers, but a couple of links to give credit for usage of assets in the application, and double-tappable icons to the iTimeZone and Tangerine Element web sites.

When you tap on any whitespace, or directly on the version number, you see the build number. To show these properties in your app, you need to know what the real names of the keys are. If you right-click on any of the properties in the Info.plist view, click Show Raw Keys/Values to see a view like this:

I created an AboutViewController with a corresponding XIB. In the viewDidLoad method, I set the UILabel to the version number by doing this:

[NSString stringWithFormat:@"Version %@",[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]];

When the user taps the view, a BOOL is used to track what state the view is in. When the build number should be changed, the UILabel is set to the the other number, so for the build number:

[NSString stringWithFormat:@"Build %@",[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]];

Wrap Up
So I think that's it. Let me first say, I am not saying you have to do an About screen in your app, I didn't have one in iTimeZone 1.0. That said, unless I am just not thinking outside the box enough on this, I can't see how to conduct a beta test without being able to check the build number, and there is simply no facility for doing that built-in to iTunes or the iPhone. You can probably hide this in your app elsewhere, but it probably needs to be there.

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...