Last active
August 29, 2015 14:24
-
-
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/)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // 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 | |
| // } | |
| // } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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