clever/you - thoughts about mobile

  • Archive
  • RSS
  • Ask Me

State Preservation & Restoration

One of the new features in iOS 6 that hasn’t exactly been shouted out from the rooftops is state preservation, probably because on paper it’s far from exciting. However, having implemented it into an app I’ve realised there are some great benefits - not least of which is making your users happier.

What it does

State preservation is designed to solve the problem of app termination. The majority of iOS users don’t know the difference between application backgrounding and application termination. Anecdotally, many people who test the apps I work on are unaware that removing apps from the ‘recent apps’ list terminates them completely.

This can result in quite a confusing and frustrating experience: sometimes coming into an app will take you back to where you were last, and at others you’ll be back to square one. Some developers had attempted to solve this by keeping track of the current app state and attempting to restore it upon relaunch. Inevitably this led to a number of different approaches, some good and some bad.

The good news is that iOS 6 now offers state preservation out of the box, and enabling it is a simple two step process:

How to enable it

Step 1: Label your Controllers

To keep track of a user’s journey through an app you need to provide restoration identifiers for your view controllers. You can identify as many or as few controllers as you wish, but only controllers with restoration identifiers present will automatically instantiated and navigated to by iOS upon launch.

If you’re working with XIBs you can add identifiers within Interface Builder - and with Storyboards it’s even easier (since Storyboards already track a user’s progress through an app). In code you can simply set the restorationIdentifier property.

Step 2: Opt In to Restoration and Preservation

Currently, state preservation is ‘opt in’. To opt in you need to implement three methods in your application delegate, described below:

- (BOOL)application:shouldRestoreApplicationState:
Sometimes you might not want iOS to automatically restore the user’s state: perhaps your app has had a major UI update, and the area of the app your user was last in no longer exists. You should return YES to enable restoration.

- (BOOL)application:shouldSaveApplicationState:
As above, except this method is called when you application is terminated. Again, return YES to allow iOS to save the most recent state information.

- (BOOL)application:willFinishLaunchingWithOptions:
To support state restoration a new launching method has been introduced that complements the more traditional didFinishLaunching. willFinish is called before the state is restored, and didFinish is called afterwards. You’ll probably therefore want to split your launching code across these two methods: code that is required for your app to run should go in willFinish. Final completion code should go in didFinishLaunching. What counts as ‘final completion code’? Things like checking whether a user is logged in, where you might want to display a modal login page rather than your app itself, for example.

Backwards Compatibility

If you’d like to support iOS 4 and 5 users (where state preservation is not supported) you’ll need to watch out for a few things. Firstly, be sure to test that restoration identifiers are supported using respondsToSelector (if you’re using IB you can skip this step):

if ([self respondsToSelector:@selector(restorationIdentifier)]) {
        self.restorationIdentifier = @"Home Controller";
}

However, a more serious issue is how to deal with the new willFinishLaunchingWithOptions method, which is only available on iOS 6, into which you’ve moved most of your launching logic. You could put your launch code into both willFinish and didFinishLaunching and conditionally test the current version of iOS, but this is unnecessary duplication.

Instead, you can use this great little trick which Apple recommend in their WWDC videos:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self commonLaunchInitialization:launchOptions];

    // Code that must execute in didFinishLaunching whether state restoration is enabled or not
    return YES;
}

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self commonLaunchInitialization:launchOptions];
    return YES;
}

- (void)commonLaunchInitialization:(NSDictionary *)launchOptions {
    static dispatch_once_t pred;
    dispatch_once(&pred, ^{
    // Your launch code here
});

If you are not familiar with Grand Central Dispatch you’re probably wondering what this code does. The dispatch_once GCD call is a clever method that is typically used when doing singleton work: it will execute it’s code block once only, and no nothing for any subsequent calls. This allows us to guarantee our launch logic will only be executed once, even though we’re calling commonLaunchInitialization in both didLaunch and willLaunch.

A Note on Testing

For reasons that will become quickly apparent, there are a few ‘gotchas’ involved with testing state restoration. Confusingly, terminating an app from the app switching pane disables restoration. Why? To prevent a mis-behaving or broken app from keeping a user stuck inside a loop. Perhaps the app has some terrible networking code that keeps the user locked inside a loading screen - resuming to that state would not be beneficial. Similarly, as you might expect state will not be resumed if your app didn’t terminate cleanly (i.e, it crashed).

So how do you test app switching? Well, when attached to the debugger you will want to exit to the home screen (by pressing the home button) and then terminate the app from Xcode (by hitting the ‘Stop’ button).

    • #ios
    • #ios6
    • #Mobile Development
    • #state preservation
    • #ios sdk
    • #iphone development
  • 2 months ago
  • Permalink
Share

Short URL

TwitterFacebookPinterestGoogle+

iOS Betas: Don’t Pay For Them

Every year, Apple release a new version of iOS…and every year, people try to make some money selling access to iOS betas.

I would like to implore developers and the public alike to stop the madness:

Public: Don’t Pay for It

iOS Betas are buggy, buggy, buggy

It’s not unknown for beta versions of iOS to severely cripple your battery life, crash regularly, and generally cause problems. It isn’t worth it. I promise you.

It makes developers sad :(

There have been several instances when non-developers installed betas and gave apps that didn’t work poor reviews on the store. This was particularly apparent when the iOS 5 betas came out: Apple made significant changes to how UI elements were customised, which caused many apps to break. Developers were understandably annoyed by this, since the whole point of the betas is to allow developers to fix these problems.

Betas expire or lock

Apple can and do ban developers who they discover are selling access - and will also lock any devices running betas that are registered to those developers. You will need to go back to iTunes and downgrade your phone to the most recent public version of iOS to get up and running again - and since selling access to betas is definitely not kosher, don’t expect a refund. This is the minority of cases: what’s more likely is your beta will expire, and you’ll end up having to re-install another one (or downgrade). It’s not worth the extra effort, particularly if your phone stops working when you’re out on the road or in the middle of nowhere.

If you MUST have it…

…I suspect some people in this world just really want the latest thing on their phone. So if you choose to ignore all my advice above, just promise me this:

  • Don’t review apps that aren’t playing nice - wait until iOS 6 is released to the public and give developers a chance to fix any problem.
  • Avoid paying for beta access if you can. Paying simple encourages the problem.

Developers: Don’t Do It

You will be found out

OK, you probably won’t be found out, but that’s only because there are a number of developers considerably dumber than you. One of my favourite is the person behind iosreg.com, which offers beta access for the ‘low’ price of ~$10 (that’s a $900 profit off each developer account, by the way - even more if you’re using an enterprise account).

Now, given that selling beta access is absolutely, totally in violation of your developer agreement you’d think you’d take steps to hide who you were. Not so here, because the person behind iOSReg.com has used his real name and address rather than an anonymous proxy when registering the domain. These are the people who will be found out - there are many, equally foolish, people and sites out there that don’t deserve the pagerank.

What’s clear is that Apple have in the past punished developers who sold iOS beta access. Of course, money is involved, so appealing to any sense of decency or good faith is probably a lost cause here: if you’re selling beta access you’re probably not a true iOS developer, but someone out for some fast cash. If you truly cared about iOS development you wouldn’t sell beta access because you’d understand the need for a period to allow developers to adjust their apps in private. So for that reason alone I hope this post at least encourages one person not to buy beta access.

(I wrote this rather quickly in response to a tweet: apologies for any omissions, but I just had to get it down while I was still mad!)

    • #ios
    • #developers
    • #ios6
    • #beta
  • 11 months ago
  • Permalink
Share

Short URL

TwitterFacebookPinterestGoogle+

About

I'm Nick, by day a mobile software engineer in London. Mainly I work on iOS and Objective-C, with some dabbling in Android. My views here are my own, not my employer's.

Me, Elsewhere

  • @objclxt on Twitter

Twitter

loading tweets…

  • RSS
  • Random
  • Archive
  • Ask Me
  • Mobile
Effector Theme by Pixel Union