Tuesday, October 25, 2011

iOS 5 Support for dismissModalViewControllerAnimated

Fixed an odd bug today and submitted v1.3 of Caroline's Cat Game to the store. Turns out that calling dismissModalViewControllerAnimated: for the [self parentViewController] basically stopped doing anything. When Apple makes changes that cause crashes that is bad, but at least we get some kind of alert. This just makes a button stop doing anything. No crash, no error, no nothing.

Anyway, if you are here because your calls to parentViewController have stopped working, here is the code we are now using. It appears that we need to use "presentingViewController" as well as a new call to dismissViewcontrollerAnimated. This all seems to be related to storyboards in iOS 5. Here is a link to the updated UIViewController documentation that talks about parentViewController and presentingViewController and the new dismissViewControllerAnimated. Right here below, is how we have set up our button to respond to being clicked. In the old days (last month) the method just had the   [[self parentViewControllerdismissModalViewControllerAnimated:YES] line but we have to add a little more now.

    if ([[self parentViewController] respondsToSelector:@selector(dismissModalViewControllerAnimated:)]){
        [[self parentViewController] dismissModalViewControllerAnimated:YES];
    } else {
        [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];

We have wrapped the whole call into an if statement so that we can still use the old way when on an older phone. The respondsToSelector: test is a good way to deal with using old and new code together. Trying to test for a specific version of iOS by name is pretty brittle; always use the respondsTo method instead.

Friday, October 21, 2011

Setting Up Xcode to Support Old iPhones

The iPhones from v1 to v3G all use the armv6 architecture
The iPhone 3GS and above all use the armv7 architecture (this is why it is not a really big deal that Apple has decided to continue to sell the iPhone 3GS)

The phones that run the armv6 are mostly on iOS 3.1.3. It is possible to pus 4.2.1 on an iPhone 3 but it runs so….very…..slowly….that most people have downgraded back to 3.1.3 or else bought a new phone. The 3GS runs iOS 4.x and 5.x pretty well so there is no reason for people with a 3GS or above not to be on 4x or 5x. The 3GS had some issues with iOS 4.0 but those speed issues have been addressed and any 3GS you purchase today will have IOS 5 on it.

As is their general theme, Apple hates supporting old things so the defaults in Xcode 4 (and 4.2 which is the current version) assume that everyone is running iOS5 and that they have a 3GS or better device. That is a reason the simulator only has options for 4.3 and 5.0 software. If you read this article from Apple Insider you will get a nice graphic showing how hard Apple is pushing iOS 5 and on what devices it runs.

To make your Xcode compile code for an old iPhone you have to do two things:
In Build Settings for your target, change the "Compiler for C/C++/Objective-C to LLVM GCC 4.2 (this is not the default)
In Build Settings for your target, change the "Architectures" from "Standard (arm7)" to "armv6 armv7"

You should also check these two settings since Xcode is going to want to have the Deployment Target be the latest version of the OS by default.
In Build Settings for your target, make sure that "iOS Deployment Target" is set to "iOS 3.0" or whatever the minimum you will support is
In Build Settings for your target, make sure that "Base SDK" is set to "Latest iOS (iOS 5.0)"

Now, you should be able to install and compile things on the old phones. The above settings are for ALL projects you create where you want to support older devices.

Update: Others are having this problem and posting similar fixes. I think I like this fix for the armv6 issue over at Retro Dreamer better.