Cocoa with Love

Advanced programming tips, tricks and hacks for Mac development in C/Objective-C and Cocoa.

Network data requirements on iPhone OS devices

If your iPhone OS application makes heavy use of the network, there are a few extra settings your application will require to ensure the network works correctly and Apple will approve your application. These requirements are not always obvious (some are documented, others are only implied in documentation). I thought I'd share them so that you can avoid network dropouts and unnecessary App Store rejections.

Info.plist settings

If your iPhone/iPad/iPod Touch application uses a WiFi network connection at all, you should enable UIRequiresPersistentWiFi (Application uses Wi-Fi) in your application's Info.plist. Without this setting, the device will put its WiFi connection to sleep after 5-30 minutes.

I've mentioned this setting in a previous post but I feel it is worth repeating since it is an easy flag to overlook and it leads to unexpected network dropouts if it isn't set.

There are other Info.plist settings, including the UIRequireDeviceCapabilities (Required device capabilities) value "wifi" which you can enable if you choose but it does not appear to have any effect at this time.

Reachability

If your application runs on WiFi only or 3G only, then you are required to test this and present an error to the user if the wrong network is in use. This is a usability requirement that Apple enforces and your application will be rejected if it isn't followed.

Apple provide the Reachability sample application to show how you can test for network availability. Internally, this class uses the SCNetworkReachability API but it's much easier to borrow the entire Reachability class from this example program and invoke:

if ([[Reachability reachabilityForLocalWiFi] currentReachabilityStatus] == ReachableViaWiFi)
{
    // perform action that requires a local WiFi connection
}
else
{
    // give a message that local WiFi is required
}

A quick warning about this: the WiFi connection can take 10 seconds or more to wake up after the device is woken up from sleep. If WiFi is not available, you may want to set a timer and try again for the next 5-10 seconds before presenting an error.

3G data throttling

If your application uses continuous data over 3G, you are required to throttle this data, rather than perpetually use the maximum available.

What do I mean by this?

As an example: I wrote an application for a client that downloaded music tracks to the phone and then played these tracks from the locally stored cache. The download of the track was not speed limited and Apple initially rejected the application for making excessive use of 3G.

This guideline is somewhat fuzzy. Apple did not give a specific data rate to which the application should limit itself. I do wonder if they didn't realize that the audio wasn't actually streaming but a progressive download.

In any case, throttling the download at 128kbps allowed the application to be approved.

How do you throttle a download? With an NSURLConnection, you can't.

I used the following crude but easy to implement approach. First, I switched from NSURLConnection to a CFReadStream. Then, in the ReadStreamCallback, I tracked the data downloaded over a small time window and if data downloaded exceeded the allowance for that window, simply

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.