iPhone SDK 3 and Deprecated Method Warnings

A side-effect of developing code on platforms that continue to evolve, is dealing with methods that become deprecated from one release to another. If you’ve spent anytime at all with Java, you are all too familiar with this concept. With the release of the iPhone SDK version 3.0, a number of methods have been become subject to the same fate.

Here is how I came about this in my most recent app. I have a subclass of UITableViewCell that looks as follows:

@interface WeaponCell : UITableViewCell 
{
  UIImageView *image; 
  ...
}
 
...
 
// An instance of WeaponCell
WeaponCell *cell;

Prior to installing the 3.0 SDK, I would set the image as follows:

  cell.image = [UIImage imageNamed:@"weapon.png"];

However, with 3.0, the image method for UITableViewCell now states this: “Deprecated. Instead use the imageView property to get UIImageView object and then get or set the encapsulated image.”

Trouble is, you can’t simply make the appropriate code change if there’s any chance you need to build for a device that is running 2.x (or earlier). For example, I had to create an adhoc release today for someone who is running a device that has not been upgraded, and rolling back the code to pre-3.0 was not on the agenda. Here’s a much better solution:

// That's two underscores before IPHONE
#if __IPHONE_3_0
  cell.imageView.image = [UIImage imageNamed:@"weapon.png"];
#else
  cell.image = [UIImage imageNamed:@"weapon.png"];
#endif

Likewise, the font property of UIButton has been deprecated and you now are directed to use titleLabel property instead.

UIButton *backButton = [[UIButton alloc] initWithFrame:frame];
 
#if __IPHONE_3_0
  backButton.titleLabel.font = [UIFont systemFontOfSize:15.0];
#else
  backButton.font = [UIFont systemFontOfSize:15];
#endif

Deprecated methods, one of those things that you get to live with as a software developer. Good news is, there are reasonable work-arounds that make for managing this issue pretty painless.

  1. The most often met deprecation warning is related to the cell.text.

    UITableViewCell in SDK 3 offers textLabel and detailTextLabel:

    #if __IPHONE_3_0
    cell.textLabel.text = @”The Text”;
    cell.detailTextLabel.text = @”The Sub-text”;
    #else
    // cell with the custom content view
    cell.text = @”The Text”
    cell.customSubTextLabel = @”The Sub-Text”
    #endif

    Editor’s note: cell.customSubTextLabel does not exist in 2.x. To have functionality similar to the 3.0 cell.detailTextLabel, you would have to add a custom label to a subclass of cell.

  2. I’ve been using similar code, but my problem is this: what happens when the version goes up to 3_1? Now that code is going to revert to the pre 3.0 version. Is there some way to do a “if version < 3” test?

  3. Mike,

    If you are targeting an SDK prior to 3.0 the preprocessor variable __IPHONE_3_0 is undefined so the else part is used. Now if you are compiling for an SDK equal to or after 3.0 the variable WILL be defined so the then part is used. No need to do a comparison.
    To check how this works just have a look at Availablity.h in the SDK.
    As you see all previous versions are defined as well:

    #define __IPHONE_2_0 20000
    #define __IPHONE_2_1 20100
    #define __IPHONE_2_2 20200
    #define __IPHONE_3_0 30000
    #define __IPHONE_NA 99999 /* not available */

    If you really want to do a comparison, the comments in Availability.h recommend this:

    #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000
    // code for OS3.0 and later
    #else
    // code for earlier versions
    #endif

  4. So do you release two different versions of your app, one for = 3.0? Or do both of these get put into a “universal binary” for the iPhone?

    • Chris,

      iPhone apps are targeted for one base platform. For example, if you create a build for 2.2.1, you typically do not include features of the 3.0 SDK, one way around this is weak linking, see Simon’s comment.

      John

Comments are closed.