Ios 如何在Xcode 8中使用Swift 3创建managedObjectContext?

Ios 如何在Xcode 8中使用Swift 3创建managedObjectContext?,ios,xcode,swift,core-data,swift3,Ios,Xcode,Swift,Core Data,Swift3,在视图控制器中尝试创建新上下文时,面临问题“类型为'AppDelegate'的值在新的Xcode 8(使用Swift 3,iOS 10)中没有成员'managedObjectContext' let context = (UIApplication.shared().delegate as! AppDelegate).managedObjectContext 在Xcode 8中,AppDelegate.swift文件中没有managedObjectContext的代码。AppDelegate.

在视图控制器中尝试创建新上下文时,面临问题“类型为'AppDelegate'的值在新的Xcode 8(使用Swift 3,iOS 10)中没有成员'managedObjectContext'

let context = (UIApplication.shared().delegate as! AppDelegate).managedObjectContext
在Xcode 8中,AppDelegate.swift文件中没有managedObjectContext的代码。AppDelegate.swift中的核心数据堆栈代码仅显示为:lazy var persistentContainer:NSPersistentContainer属性和func saveContext()。没有managedObjectContext属性


如何在Xcode 8)中使用Swift 3创建managedObjectContext,或者可能不需要使用Swift 3创建managedObjectContext?

NSPersistentContainer
有一个
viewContext
属性,它是
NSManagedObjectContext
类型


作为补充说明,如果您在Xcode 8中创建一个主细节应用程序,Apple的示例代码将
managedObjectContext
属性放在MasterViewController.swift文件中,并使用AppDelegate中的
viewContext
属性进行设置。

NSPersistentContainer
具有
NSManagedObjectContext
类型


作为补充说明,如果您在Xcode 8中创建一个主细节应用程序,Apple的示例代码会将
managedObjectContext
属性放在MasterViewController.swift文件中,并使用AppDelegate中的
viewContext
属性进行设置。

在Swift3中,您可以通过viewContext作为

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
如果在创建项目时启用了核心数据,则此选项可用。但是,对于要包含核心数据的现有项目,请执行添加核心数据的正常过程,并添加以下代码,这将允许您获取

lazy var persistentContainer: NSPersistentContainer = {

    let container = NSPersistentContainer(name: "you_model_file_name")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error {

            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()
您将需要导入CoreData

注意:对于Swift3,ManagedObject子类是自动生成的。
在Swift3中查看更多信息,您可以通过viewContext访问managedObjectContext,如下所示:

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
如果在创建项目时启用了核心数据,则此选项可用。但是,对于要包含核心数据的现有项目,请执行添加核心数据的正常过程,并添加以下代码,这将允许您获取

lazy var persistentContainer: NSPersistentContainer = {

    let container = NSPersistentContainer(name: "you_model_file_name")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error {

            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()
您将需要导入CoreData

注意:对于Swift3,ManagedObject子类是自动生成的。 查看

解决方案的更多信息,该解决方案为iOS 10.0提供了大部分解决方案,但没有解决iOS 9.0及以下版本的问题,因为iOS 9.0及以下版本无法访问该方法,需要手动构建
NSManagedObjectModel
。以下是适用于我的解决方案:

    var context: NSManagedObjectContext?

    if #available(iOS 10.0, *) {
        context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    } else {
        // iOS 9.0 and below - however you were previously handling it
        guard let modelURL = Bundle.main.url(forResource: "Model", withExtension:"momd") else {
            fatalError("Error loading model from bundle")
        }
        guard let mom = NSManagedObjectModel(contentsOf: modelURL) else {
            fatalError("Error initializing mom from: \(modelURL)")
        }
        let psc = NSPersistentStoreCoordinator(managedObjectModel: mom)
        context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
        let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let docURL = urls[urls.endIndex-1]
        let storeURL = docURL.appendingPathComponent("Model.sqlite")
        do {
            try psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil)
        } catch {
            fatalError("Error migrating store: \(error)")
        }

    }
很明显,对10.0的更改使CoreData变得非常简单,但不幸的是,对于现有开发人员来说,跳转是如此痛苦

要实现上述功能,只需确保将
persistentContainer
放入您的AppDelegate.swift中(在的答案中定义)。

解决方案为iOS 10.0提供了大部分解决方案,但没有解决iOS 9.0及以下版本,后者无法访问该方法,需要手动构建
NSManagedObjectModel
是对我有效的解决方案:

    var context: NSManagedObjectContext?

    if #available(iOS 10.0, *) {
        context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    } else {
        // iOS 9.0 and below - however you were previously handling it
        guard let modelURL = Bundle.main.url(forResource: "Model", withExtension:"momd") else {
            fatalError("Error loading model from bundle")
        }
        guard let mom = NSManagedObjectModel(contentsOf: modelURL) else {
            fatalError("Error initializing mom from: \(modelURL)")
        }
        let psc = NSPersistentStoreCoordinator(managedObjectModel: mom)
        context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
        let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let docURL = urls[urls.endIndex-1]
        let storeURL = docURL.appendingPathComponent("Model.sqlite")
        do {
            try psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil)
        } catch {
            fatalError("Error migrating store: \(error)")
        }

    }
很明显,对10.0的更改使CoreData变得非常简单,但不幸的是,对于现有开发人员来说,跳转是如此痛苦


要实现上述功能,只需确保将
persistentContainer
放入您的AppDelegate.swift中(在的答案中定义)。

将所有核心数据堆栈代码移动到一个文件中,并添加了iOS10及以下iOS10。下面是我的尝试(不确定是否完全符合要求)


将所有核心数据堆栈代码移到一个文件中,并添加了iOS10及以下版本。以下是我的尝试(不确定是否完全符合要求)


首先,获取AppDelegate对象:-

let appDelegateObject = UIApplication.shared.delegate as! AppDelegate
现在,我们可以将托管对象设置为:

let managedObject = appDelegateObject.persistentContainer.viewContext

首先,获取AppDelegate对象:-

let appDelegateObject = UIApplication.shared.delegate as! AppDelegate
现在,我们可以将托管对象设置为:

let managedObject = appDelegateObject.persistentContainer.viewContext

你会想看看这篇演讲你会想看看这篇演讲我认为重要的是要注意,
nspersistentcainer
是一个iOS 10 API,与Swift 3没有特别的联系。如果你计划支持iOS 9.x,你将无法使用
nspersistentcainer
,并且需要按照你的意愿设置你的核心数据堆栈d在使用Xcode 8.Hi之前已经有过。对于Mac应用程序,有没有类似的简单方法可以做到这一点?因为
nsPersistentContainer
是iOS,第一行方法不起作用。macOS 10.12是一个受支持的SDK。我将Swift 3.0与Xcode 8.0一起使用。
UIApplication.shared()
生成如下错误消息无法调用非函数类型UIApplication的值“。但是,
UIApplication.shared
运行良好。这是一个良好的开端,但要解决此方法与iOS 9及以下版本不兼容的问题,请参阅下面的答案。我认为需要注意的是,
NSPersistentContainer
是一个iOS 10 API,与Swift 3没有特别的联系。如果您计划支持iOS 9.x,您将无法使用
NSPersistentContainer
,并且需要像使用Xcode 8.Hi之前一样设置核心数据堆栈。对于Mac应用程序,有没有类似的简单方法可以做到这一点?由于
nsPersistentContainer
是iOS,所以第一行方法不起作用。macOS 10.12是一个受支持的SDK。我正在使用Swift 3.0和Xcode 8.0
UIApplication.shared()
生成一条错误消息,如“无法调用非函数类型UIApplication的值”。然而,
UIApplication.shared
运行良好。这是一个良好的开端,但要解决此方法与iOS 9及以下版本不兼容的问题,请参阅下面的答案。我认为这正是我所寻找的。如果该类仅与同一组(针对两个应用)中的应用程序和扩展程序共享,这是否允许两个应用程序都可以访问数据?我遇到了一个键盘扩展的问题,其中