Skip to content

Instantly share code, notes, and snippets.

@sjgroomi
Last active August 29, 2015 14:24
Show Gist options
  • Select an option

  • Save sjgroomi/dcb3fbd11cc09686e685 to your computer and use it in GitHub Desktop.

Select an option

Save sjgroomi/dcb3fbd11cc09686e685 to your computer and use it in GitHub Desktop.
An asynchronous Swift 2.0 Core Data stack loosely based on Marcus Zarra's (http://martiancraft.com/blog/2015/03/core-data-stack/)
//
// SGCoreDataStore.swift
// Core Data Example
//
// Created by Groom, Stephen on 09/07/2015.
// Copyright © 2015 Stephen Groom. All rights reserved.
//
import CoreData
public enum SGCoreDataError: ErrorType {
case InvalidModelURL
}
public class SGCoreDataStore {
//These properties are implicitly unwrapped optionals, and vars rather than let because of
// https://devforums.apple.com/thread/251388?start=0&tstart=0#1062922
// http://www.openradar.me/21744509
/**
Used internally so that saving to disk is done asynchronously
*/
private var privateContext: NSManagedObjectContext!
/**
For reading on the main thread only
*/
public var mainContext: NSManagedObjectContext!
/**
For all write operations and fetches which can be performed asynchronously
*/
public var backgroundContext: NSManagedObjectContext!
init(modelURL: NSURL, storeURL: NSURL) throws {
guard let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL) else { throw SGCoreDataError.InvalidModelURL }
let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)
try persistentStoreCoordinator.addPersistentStoreWithType(NSSQLiteStoreType,
configuration: nil,
URL: storeURL,
options: [NSInferMappingModelAutomaticallyOption : true, NSMigratePersistentStoresAutomaticallyOption : true])
privateContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
privateContext.persistentStoreCoordinator = persistentStoreCoordinator
mainContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
mainContext.parentContext = privateContext
backgroundContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
backgroundContext.parentContext = mainContext
}
// A good idea but no: http://www.openradar.me/21745663
// /**
// Saves changes to all managed object contexts
//
// Can be called from any thread.
//
// **Avoid calling from the main thread as this blocks until the save is completed**
// */
// public func save() throws {
// do {
// backgroundContext.performBlockAndWait { [weak self] in
// try self?.backgroundContext.save()
// }
// mainContext.performBlockAndWait { [weak self] in
// try self?.mainContext.save()
// }
// privateContext.performBlockAndWait { [weak self] in
// try self?.privateContext.save()
// }
// }
// catch let error {
// throw error
// }
// }
}
@sjgroomi
Copy link
Author

As the model and data can potentially be quite large, a better solution might be to perform this setup asynchronously. For an example implementation see https://gist.github.com/sjgroomi/5a3ab2142d9afdf5d1ca

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment