Updating your iPhone code for iOS4

I just went through the process of upgrading Cogs to take advantage of the new capabilities of the iPhone 4. Since I had such a tough time getting everything working on all of the iOS platforms, I figured I'd make a list of my changes to help out other developers who have built apps based on Apple's OpenGL ES example.

Add the high-def icon to your info.plist:

    <key>CFBundleIconFiles</key>
    <array>
        <string>iPhone_icon.png</string>
        <string>iPhone_icon@2x.png</string>
    </array>
    <key>CFBundleIconFile</key>

Note that this needs to be added in addition to, rather than in place of your existing CFBundleIconFile in order to cooperate with older iOS versions. Also remember to update your app version.

Add new functions to your AppDelegate. Pay close attention to the comments here to understand what each function should do.

//------------------------------------------------------------------------------

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Save the state of your app so that you can restore it on a restart.
    // On iOS3.x and prior, this gets called when the user presses the home button
    // or the phone receives a call.
    // On iOS4, it also gets called if the app is in the background and the device
    // runs low on memory.
}

//------------------------------------------------------------------------------

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
    // Another app is low on memory, If possible, clean up resources that you can
    // reallocate when the app is restored.
}

//------------------------------------------------------------------------------

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Save the state of your app, just as you would have in applicationWillTerminate.

    // You may also want to set a variable to indicate that the app has been put in the
    // background.  I check this variable in my OpenGL loop to prevent rendering when
    // in this state.  A single OpenGL call to a backgrounded app will cause it to crash.
    g_bInBackground = true;
}

//------------------------------------------------------------------------------

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // The app was successfully restored.  If your saved game state that is no longer
    // needed, you can delete that data now.

    g_bInBackground = false;
}

//------------------------------------------------------------------------------

In your EAGLView class, where OpenGL drawing is done, make sure you prevent calls to OpenGL when your app is in the background:

- (void)drawView
{
    if (g_bInBackground)
        return;
    ...
}

In EAGLView.initWithCoder, before you initialize your renderer and buffers, check if this is a device that supports a higher pixel density:

    // Double the resolution on iPhone 4.
    g_scale = 1.0f;
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]
     && [self respondsToSelector:@selector(setContentScaleFactor:)])
    {
        g_scale = [UIScreen mainScreen].scale;
        [self setContentScaleFactor: g_scale];
    }

Note that calling [UIScreen mainScreen].scale on iOS3.x will cause a crash, which is why you first need to call respondsToSelector. Oddly enough, the scale function works on the iPad OS, but setContentScaleFactor is unimplemented, so you need to do a separate respondsToSelector check for that function.

Now that you've cached the scale value, you may also need to use it in places throughout the code where you need to access the exact screen resolution. Note that touch coordinates will still be given to you based on a 320x480 coordinate system.

Finally, for art assets that you want to take advantage of the higher resolution, make a second version of the art asset with @2x appended to the name, prior to the extension. That version of the artwork will automatically get loaded when the retina display is available.

That should cover the essentials. If you see anything that's missing here, drop me an email at rob@lazy8studios.com and I'll add it to the list.