在iOS

时间:2016-08-30 19:18:03

标签: ios swift core-data

我一直在做

let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

只是在我的ViewControllers中使用上下文,但在Apples iOS开发者库中我读了

"视图控制器通常不应从全局对象(例如应用程序委托)中检索上下文"

那么从AppDelegate访问上下文的正确方法是什么,我有点困惑......

1 个答案:

答案 0 :(得分:1)

你是对的,Apple并不推荐iOS应用程序。

创建CoreData堆栈是最佳解决方案:

所以在 AppDelegate.swift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?
  lazy var coreDataStack = CoreDataStack()

  func application(_ application: UIApplication,
    didFinishLaunchingWithOptions
    launchOptions: [NSObject: Any]?) -> Bool {

    let navigationController =
self.window!.rootViewController as! UINavigationController

    let viewController =
navigationController.topViewController as! ViewController

    viewController.managedContext = coreDataStack.context

    return true
  }

  func applicationDidEnterBackground(_ application: UIApplication) {
    coreDataStack.saveContext()
  }

  func applicationWillTerminate(_ application: UIApplication) {
    coreDataStack.saveContext()
  }

然后, CoreDataStack.swift 的一个例子(包含MOC所有职责的类):

import CoreData    
class CoreDataStack {

  lazy var context: NSManagedObjectContext = {

    var managedObjectContext = NSManagedObjectContext(
      concurrencyType: .mainQueueConcurrencyType)

    managedObjectContext.persistentStoreCoordinator = self.psc
    return managedObjectContext
    }()

  fileprivate lazy var psc: NSPersistentStoreCoordinator = {

    let coordinator = NSPersistentStoreCoordinator(
      managedObjectModel: self.managedObjectModel)

    let url = self.applicationDocumentsDirectory
      .appendingPathComponent(self.modelName)

    do {
      let options =
      [NSMigratePersistentStoresAutomaticallyOption : true]

      try coordinator.addPersistentStore(
        ofType: NSSQLiteStoreType, configurationName: nil, at: url,
        options: options)
    } catch  {
      print("Error adding persistent store.")
    }

    return coordinator
    }()

  fileprivate lazy var managedObjectModel: NSManagedObjectModel = {

    let modelURL = Bundle.main
      .url(forResource: self.modelName,
        withExtension: "momd")!
    return NSManagedObjectModel(contentsOf: modelURL)!
    }()

  fileprivate lazy var applicationDocumentsDirectory: URL = {
    let urls = FileManager.default.urls(
      for: .documentDirectory, in: .userDomainMask)
    return urls[urls.count-1]
    }()

  func saveContext () {
    if context.hasChanges {
      do {
        try context.save()
      } catch let error as NSError {
        print("Error: \(error.localizedDescription)")
        abort()
      }
    }
  }
}

最后是ViewController.swift的一个例子:

import CoreData    
class ViewController: UIViewController {

  var managedContext: NSManagedObjectContext!      
  override func viewDidLoad() {        

    let myEntity = NSEntityDescription.entity(forEntityName: "MyEntityName",
      in: managedContext)

    ...

  }

}