Supporting Multiple iOS Versions and Devices
There are many different iOS versions and devices out there in the wild. Supporting more than just the latest is often necessary since not all users upgrade immediately. This tutorial shows you how to achieve that goal. By Pietro Rea.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Supporting Multiple iOS Versions and Devices
50 mins
- iOS Versions: An Overview
- Getting Started
- Why Bother Supporting Multiple iOS Versions?
- Deployment Target vs. Base SDK
- Identifying Backwards Compatibility Issues
- Solving Backwards Compatibility Issues
- Supporting iOS 5 in RWRageFaces
- Working around Auto Layout in iOS 5
- Working Around Embed Segues in iOS 5
- Working Around NSAttributedString in iOS 5
- Working Around Page Transitions in iOS 5
- Working around SLComposeViewController in iOS 5
- Deploymate Sanity Check
- Supporting Multiple Devices
- Device Collection Winners
- Where To Go From Here?
Supporting Multiple Devices
This tutorial has only covered backwards compatibility as it relates to software; however, making sure your apps can run on a wide range of hardware is just as important.
The obvious hardware differences between the iPhone and the iPad won’t be covered in this tutorial. However, check out the tutorial on porting an iPhone app to iPad and the one on updating your apps to the 4-inch iPhone 5 display since they are related to the topic of supporting multiple devices.
The idea behind maintaining backwards compatibility in hardware is simple: iOS devices can have (or lack) a variety of different hardware components. Just as you performed a runtime check to verify if a particular API was available, you have to perform a runtime check to see if a hardware component is available before you attempt to use it.
But what if the device doesn’t have the hardware you need for your app? If a particular hardware component is absolutely crucial to your application, it’s best if you limit the distribution of your application to devices that have such components. Can you imagine installing a flashlight app on a device with no camera flash?
You can specify the hardware features required by your app by changing the UIRequiredDeviceCapabilities
key in your project’s Info.plist. Click on your target and navigate to Info/Required device capabilities, as shown below:
The UIRequiredDeviceCapabilities
key lets you include or exclude device capabilities such front camera, back camera, camera flash, GPS, magnetometer, gyroscope, Bluetooth and more. Refer to Apple’s Information Property List Key Reference Guide and for a full list.
Note: Right-click on the project’s Info.plist and choose Open As > Code to edit the UIRequiredDeviceCapabilities
key. The array
value will suffice if you just want to list required capabilities. However, if you want to state both required capabilities and capabilities that devices must not have, then you can convert it to a dictionary. Then you use true
or false
values for each device capability to indicate which capabilities are required and which must not be present.
Note: Right-click on the project’s Info.plist and choose Open As > Code to edit the UIRequiredDeviceCapabilities
key. The array
value will suffice if you just want to list required capabilities. However, if you want to state both required capabilities and capabilities that devices must not have, then you can convert it to a dictionary. Then you use true
or false
values for each device capability to indicate which capabilities are required and which must not be present.
When a hardware component is not critical to your application, you may choose to hide or disable it if the component is not present. For example, you can use the following two methods to check if a device has a back or a front camera:
if ([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear]) {
//safe to use back camera
}
if ([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront]) {
//safe to use front camera
}
isCameraDeviceAvailable:
is available as of iOS 4.0. You have to do a few additional checks if your deployment target is earlier than iOS 4.0, which should be unlikely at this point!
UIImagePickerController
is also helpful for checking if your camera has flash capabilities and video recording capabilities.
To check if your device supports a microphone, use the following AVFoundation API:
AVAudioSession *session = [AVAudioSession sharedInstance];
if (session.inputIsAvailable) {
//safe to use microphone
}
inputIsAvailable
is deprecated as of iOS 6. Use inputAvailable
instead if your deployment target is iOS 6 or above.
Additionally, you can use Core Motion’s CMMotionManager
to detect if your device has a gyroscope, a magnetometer or an accelerometer.
CMMotionManager *motionManager = [[CMMotionManager alloc] init];
if (motionManager.gyroAvailable) {
//safe to use gryoscope
}
if (motionManager.magnetometerAvailable) {
//safe to use magnetometer
}
if (motionManager.accelerometerAvailable) {
//safe to use accelerometer
}
gyroAvailable
and accelerometerAvailable
are available as of iOS 4. magnetometerAvailable
, on the other hand, is available as of iOS 5. To check for a magnetometer prior to iOS 5, use CLLocationManager
‘s headingAvailable
API, which is available in the Core Location framework.
There are a few more hardware components you could check for that haven’t been covered here. The main takeaway, however, is that you should never assume that a particular hardware component is present on a device, as that assumption might not hold true for older devices — or for newer ones!
Device Collection Winners
As promised, here are the coolest iOS collections from users that responded to Ray’s tweet.
Longest straight line (@libovness):
Most beautiful Collection (@blakespot):
Biggest collection (@_DavidSmith):
Having your own collection of test devices is not only cool to look at, but is really helpful during development and testing.
Where To Go From Here?
Congratulations! You’ve succesfully navigated the art and science of backward compatibility on iOS. Here is the completed RWRageFaces project — fully compatible on iOS 5 and iOS 6.
Even though the tutorial dealt mainly with iOS 5 and iOS 6, the techniques presented here such as runtime checks, introspection and weak linking will be useful for many more iOS versions to come.
Always keep in mind that not everyone is a power user. If you pay close attention to backwards compatibility, your users will definitely thank you for making sure your applications are well supported on whichever system they are running.