Thursday, October 14, 2010

A Fix for a Seemingly Random iOS App Network Failure

Or How do I display the WiFi connection dialog?

If you're writing an iPhone, iPod touch or iPad app that uses the network, it's important that you set the UIRequiresPersistentWiFi key in your Info.plist file, otherwise your app may occasionally fail to connect to any network resources it requires. You will never see this failure in the simulator, or on an iPhone that has cellular service activated. Let me explain.

In order to conserve battery, iOS devices disconnect any active Wi-Fi connection after 30 minutes if the device is idle or asleep, unless the currently running app has the UIRequiresPersistentWiFi key set. If an app does not have this key set, the system doesn't automatically try to reestablish a Wi-Fi connection, even when your app tries to connect to the network.

The simulator uses your Mac's network connection—it never prompts you to connect via Wi-Fi. An iPhone with active cellular service will automatically use the cellular data network if the Wi-Fi transmitter is asleep.

You can test this on an iPod touch or Wi-Fi iPad, or on an iPhone in Airplane Mode with Wi-Fi turned on. In the Settings app, tell the device to forget any current Wi-Fi network; this will disconnect the Wi-Fi transmitter and turn it off. Then run your app. If you don't have UIRequiresPersistentWiFi set, the device won't prompt you to establish a Wi-Fi connection and any attempts your app makes to connect will fail.

When your app has UIRequiresPersistentWiFi set, the device will automatically connect to known Wi-Fi networks or pop up the standard Wi-Fi connection dialog if no known Wi-Fi network is available, and will maintain the connection while your app is active. This is especially critical for users of Wi-Fi only devices. If users complain that they sometimes have to open Safari or another app in order to get the network to connect, you forgot to set UIRequiresPersistentWiFi in your Info.plist.

One little annoyance: in Xcode (currently at version 3.2.4), the Info.plist editor doesn't include UIRequiresPersistentWiFi in the drop-down list of keys. In order to add it, create a new row and just type UIRequiresPersistentWiFi into the Key field, then right-click on the Value field and choose Value Type -> Boolean from the menu. Alternately, in the Groups & Files tree, right click on the Info.plist file and select Open As -> Source Code File from the menu. Then you can simply add
to the <dict> tag in the <plist> tag.


Lobato said...

I can't remember if I did anything different on my Xcode, but if you select the Info.plist file, and on the menus pick View > Property List Type > iPhone Info.plist (which is different from Info.plist), the new keys description have all been added, including UIRequiresPersistentWiFi

Don McCaughey said...

Cool, maybe it's included by default in newer projects. I was working on updating an older app with some new web functionality when I ran into this problem, so it might not have been there by default at one time.