Developing iPhone Apps with iOS4 SDK, Deploying to 3.x Devices : Base SDK and iPhone OS Deployment Target

Editor’s Note:You can download and install any previous release of Xcode if you would like to roll back to an earlier version. You can get the specifics here: Download and Install Older Versions of Xcode.

If you’ve installed Xcode 3.2.3 you quickly became aware that the only SDK’s packaged with this version are 4.0 and 3.2. Until 4.x has widespread adoption, chances are you’ll want your applications to run on earlier versions of the iPhone OS (iOS) SDK. You can accomplish this feat through two configuration options within Xcode, the Base SDK and the iPhone OS Deployment Target.

Base SDK

The Base SDK is the version of SDK that will be used when compiling your application – the compiler will use the headers and libraries of this specific SDK. For example, in the image below notice that there are only two choices for the Base SDK for both the device and simulator, versions 3.2 and 4.0.

However, we have an issue here, if you build an application with the latest SDK and deploy on a device with an earlier OS, chances are your application will crash if you reference any code in a 4.x API while running the application on a 3.x device. Also, the 3.2 SDK is for the iPad only, so this isn’t an option when deploying to an iPhone or iPod touch.

iPhone OS Deployment Target

To specify which OS version is the minimum that your application will support, you set the deployment target. Your application will then run on this minimum OS as well as all later versions.

This is all well and good, however, the obvious question is how to deploy on an earlier OS version yet take advantage of features for those devices that are running a later OS?

Check for Feature Availability Not OS Version

When targeting an earlier OS as mentioned above, yet you want to take advantage of features of a later OS for devices that support it, you can use the method respondsToSelector to check if the receiver implements or inherits a method that can respond to a specified message. This approach follows Apple’s recommendation to check for availability of features versus a specific OS version.

In the example below the code will check if the object returned by [UIDevice currentDevice] will respond to the selector shown, if so, you can write relevant multi-tasking code:

if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)])
{
  // Multi-tasking code for supported devices
}
else
{
  // Devices without multi-tasking support
}

Another time when that you may choose to use respondsToSelector is for cases when the implementation of the same API has changed with a later OS version. I ran into this particular case when writing code for displaying movies using the MPMoviePlayerController. In the 4.x SDK the notifications have changed slightly – in 2.0 to 3.1 MPMoviePlayerContentPreloadDidFinishNotification was the notification you would use to receive notice that a movie was ready to play. With 3.2 (iPad) and later, MPMoviePlayerContentPreloadDidFinishNotification has been deprecated and MPMoviePlayerLoadStateDidChangeNotification has taken its place.

The code example below shows how you may go about using respondsToSelector to figure out which notification you should request based on the whether or not the movie player can return information about its load state:

MPMoviePlayerController *mp = 
   [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
 
// This method is available on 3.2 and greater...
 if ([mp respondsToSelector:@selector(loadState)]) 
{
  // Register to receive notification when load state changed
  // (check for playable, stalled...)
  [[NSNotificationCenter defaultCenter] addObserver:self 
                       selector:@selector(moviePlayerLoadStateChanged:) 
                       name:MPMoviePlayerLoadStateDidChangeNotification 
                       object:nil];
 
}
else
{
  // Register to receive a notification when the movie is ready to play.
  [[NSNotificationCenter defaultCenter] addObserver:self 
                         selector:@selector(moviePreloadDidFinish:) 
                         name:MPMoviePlayerContentPreloadDidFinishNotification 
                         object:nil];
 
}
Check for Function Availability

Beyond working with objects, if you need to check for the availability of a specific function, you do so by comparing the function to NULL. In the example below I check for a function related to creating a PDF-based graphics context (available in 3.2 and later).

if (UIGraphicsBeginPDFContextToFile != NULL)
{
  // The function is available
}
Testing Across OS Versions

Unfortunately, with the upgrade to the latest Xcode (3.2.3) there are no simulators for 3.1.x and earlier OS versions. Although it has always been recommended to test your apps on device, at this point it becomes a necessity.

21 comments

Can i ask how many devices you use for testing, and how you verify that everything works as expected on each OS version you support? It seems a real shame to me that the simulator limits the versions that you can test against. I understand that there is no substitute for testing on a real device but by the same token it gets pretty expensive if a lone developer needs one of every device apple makes.

by Matt on Jul 6, 2010. #

As you say: if you depend on 4.0, your app will crash. So you must test on 3.1.

Turns out, this is where many of us have no option. The simulator doesn’t contain 3.1 and downgrading the 3GS isn’t possible, either.

Beta 2 used to have 3.1 in the simulator. Anyone know where it still can be downloaded?

by nik on Jul 6, 2010. #

Matt, I’ve been testing on a 3.1.3 device as well as a 4.0 device. So far this seems adequate as I haven’t noticed significant differences in the prior 3.1 and 3.0 versions.

It would be nice to have the prior simulators added back into Xcode.

by John Muchow on Jul 6, 2010. #

I just down graded my 3G device from 4.0 back to 3.1.3. Works great, 4.0 on my 3G was super slow and unreliable.

by nexus6 on Jul 6, 2010. #

@nik
just do a search in google for

downgrade 4.0 to 3.1…

PS. No jail breaking required

by nexus6 on Jul 6, 2010. #

@nexus6
i had the same problem: my 3G was so slow and i was ready to rollback to 3.1.3, BUT just few seconds before do it i read that a Reset of Network Settings did magic improves. I did and believe that now my 3G is with iOS4 running very good (ok not as smooth as 3.1.3 but usable).

by nebula_1979 on Jul 7, 2010. #

Geez, that was so simple way to keep development on all OS’es possible and Apple pulled the plug on it!
I guess they wanted to say everyone that it’s time to throw away your 2G/3G.

by Tonik on Jul 8, 2010. #

When submitting an app for approval, what do we answer when “itunes connect” asks “is this a OS 4 app”?

… if we want *ONLY* 0S4….

or….

… if we want *BOTH* OS4 and OS3 support.

by Alice on Jul 15, 2010. #

I think this will come down to how you set the Deployment target. If you choose a deployment target of 4.0, the app will only run on a 4.0 device. If you set target to 3.x, the app will run on 3.x and all later versions…

by John Muchow on Jul 15, 2010. #

Thanks for this explanation. I really wanted to support 3.1.3 devices but build with SDK4, and now I know how! I’m still a little fuzzy on the difference between a project and a target. Can anyone enlighten me?

Thx!

by Steve Fogel on Jul 18, 2010. #

A target is simply the lowest OS version that will be supported by your app.

by John Muchow on Jul 18, 2010. #

Hi,

I’d like my app to provide the nice iOS 4 feature of resuming in the way I left it.
I noticed that I get this feature for 4 – but only if I set the deployment OS to 4.0.

Is there no way to get this behavior for iOS 4 while not losing 3.1.x compatibility?

Thanks

by Reuven on Jul 21, 2010. #

Reuven,

You should be able to set the base sdk to 4.0 and target to 3.1.x and then use code approach I mentioned to check for availability of various methods to know if the device supports the 4.x features you want to use.

by John Muchow on Jul 21, 2010. #

Hi john,
Thanks for your tip on how to run iOS4 and the earlier versions. please can you give me a brief outline of how to install the older iOS3.x SDK as I have iOS4 installed and following your links I just downloaded the older iOS3 but I fear that if i try to install it, it will erase the iOS4 I have installed.
Thanks

by Bivins on Aug 4, 2010. #

Bivins, please look over here for more information on installing multiple versions of Xcode: Download and Install Older Versions of Xcode

by John Muchow on Aug 4, 2010. #

Hi John,

Following your instructions I’m getting a ‘Warning’ message when testing my app on my device.

‘Warning: Building with ‘Targeted Device Family’ set to iPhone only (‘1’) not supported with SDK ‘Device – iPhone OS 3.2’.

I’ve built my project on Xcode 3.2.3 Set the Base SDK to 3.2 and Development Target as iOS 3. My iPhone is running on iOS 4.1.

How to rectify this problem.

Appreciate your help.

Many thanks.

by Sid on Aug 23, 2010. #

Sid, 3.2 is only available for the iPad. I would recommend changing your Base SDK to 4.0 and setting the target to the desired platform.

by John Muchow on Aug 23, 2010. #

Thanks so much. No more warning. :)

by Sid on Aug 23, 2010. #

Thanks John, I was just looking for this guide.

by Amit on Dec 29, 2010. #

When newer OS versions come out, I don’t overwrite the “Developer” folder but rather put the newest version in a folder called “Developer 3_2_x”. That way, I can open up xCode is each version I have. The only downside is that each folder you create is about 5-6GB’s. But if you have a large HD, you should be fine.

by Tony on Jan 14, 2011. #

Anyone of you, will you please tell me about how to install application supporting iOS 4+ on iOS 3?
Actually i am using iPhone 3G with iOS 4.2.1 but its getting damn slow day by day.
So i have decided to downgrade it to iOS 3. But the apps like whatsapp, nimbuzz, skype, and other games which works now on iOS 4.2 won’t be working on iOS 3.0..!!! So can you guys please help with this about how can i install the apps supporting iOS 4.2…..
Thanks in advance..!!

by Amit on Jan 10, 2012. #