I’ve seen this question in various forms without a clear answer. I’m going to ask and answer here. My app needs to do work on startup… inits, a few network calls, login, etc. I don’t want my main view controller working until that’s done. What’s a good pattern for doing this?
Requirements:
- iOS5+, storyboards, ARC.
- the main vc’s view cannot appear until the startup work is done.
- want a choice of transition styles to the main vc when the startup work is done.
- want to do as much layout as possible in storyboard.
- the code should be cleanly contained somewhere obvious.
EDIT, July 2017
Since the first writing, I’ve changed my practice to one where I give the start up tasks to their own view controller. In that VC, I check startup conditions, present a “busy” UI if needed, etc. Based on the state at startup, I set the window’s root VC.
In addition to solving the OP problem, this approach has the additional benefits of giving better control of the startup UI and UI transitions. Here’s how to do it:
In your main storyboard, add a new VC, called
LaunchViewControllerand make it the app’s initial vc. Give your app’s “real” initial vc an identifier like “AppUI” (identifiers are on the Identity tab in IB).Identify other vcs that are the starts of main UI flows (e.g. Signup/Login, Tutorial, and so on) and give these descriptive identifiers, too. (Some prefer to keep each flow in it’s own storyboard. That’s a good practice, IMO).
One other nice optional idea: give your app’s launch storyboard’s vc an identifier, too (like “LaunchVC”), so that you can grab it and use it’s view during startup. This will provide a seamless experience for the user during launch and while you do your startup tasks.
Here’s what my
LaunchViewControllerlooks like….The original answer below, though I prefer my current approach
Let’s express the app’s readiness to run the main vc with a boolean, something like:
In the AppStartupViewController.m, when the readyToRun conditions have been met, it can dismiss itself:
Now, whenever the app becomes active, it can check for readiness to run, and present the AppStartupViewController if it’s needed.
In AppDelegate.h
That’s mostly the answer, but there is one hitch. Unfortunately the main vc gets loaded (that’s okay) and gets a viewWillAppear: message (not okay) before the AppStartupViewController is presented. It means we have to spread a little extra startup logic, like this, in MainViewController.m:
I hope this is helpful.