Documentation Archive


Core Data Programming Guide

On This Page

Integrating Core Data at iOS Startup

The beginning of an application life cycle is subtly different in iOS and macOS.

When an macOS application takes an unusually long time to launch and becomes unresponsive, the operating system changes the cursor to indicate this state. The user can then decide to wait for the application to finish launching or quit the application.

In iOS, there is no such concept. If an app does not launch within a finite amount of time, the operating system terminates the application. Therefore, it is vital that an application complete the startup procedure as quickly as possible.

On the other hand, you want your application to be able to access data inside of Core Data as quickly as possible, which usually means initializing Core Data as one of the first steps in the application’s life cycle. Although atypical, Core Data occasionally takes longer than usual to complete its initialization.

Therefore, it is recommended that the startup sequence of an iOS app be broken into two phases, to avoid termination:

  1. A minimal startup that indicates to the user that the application is launching

  2. Complete loading of the application UI after Core Data has completed its initialization

Initializing Core Data in iOS

The first step is to change how the application:didFinishLaunchingWithOptions: method is implemented. In the application:didFinishLaunchingWithOptions: method, consider initializing Core Data and doing very little else. If you are using a storyboard, you can continue to display the launch image during this method.

As part of the initialization of Core Data, assign the adding of the persistent store (NSPersistentStore) to the persistent store coordinator (NSPersistentStoreCoordinator) to a background queue. That action can take an unknown amount of time, and performing it on the main queue can block the user interface, possibly causing the application to terminate.

Once the persistent store has been added to the persistent store coordinator, you can then call back onto the main queue and request that the user interface be completed and displayed to the user.

Separating Core Data from the Application Delegate

Previously in iOS, the Core Data stack was typically initialized within the application delegate. However, doing so causes a significant amount of code to get muddled in with application life cycle events.

Create the Core Data stack within its own top-level controller object, and configure the application to initialize that controller object and hold a reference to it. This action promotes the consolidation of the Core Data code within its own controller and keeps the application delegate relatively clean. This isolated controller design is shown in detail in Initializing the Core Data Stack.

To integrate the code from the Initializing the Core Data Stack section into an iOS app, add a property to the application delegate and initialize the controller in the applicationDidFinishLaunching life cycle method:


  1. @interface AppDelegate : UIResponder <UIApplicationDelegate>
  2. @property (strong, nonatomic) UIWindow *window;
  3. @property (strong, nonatomic) DataController *dataController;
  4. @end
  5. @implementation AppDelegate
  6. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  7. {
  8. [self setDataController:[[DataController alloc] initWithCompletionBlock:^{
  9. //Complete user interface initialization
  10. }]];
  11. return YES;
  12. }
  13. @end


  1. class AppDelegate: UIResponder, UIApplicationDelegate {
  2. var window: UIWindow?
  3. var dataController: DataController!
  4. func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
  5. dataController = DataController() {
  6. //Complete user interface initialization
  7. }
  8. return true
  9. }

By initializing a separate controller object, you have moved the Core Data stack out of the application delegate, but you still allow access to Core Data throughout the application.