【问题标题】:Looking for a clear tutorial on the revised NSPersistentContainer in Xcode 8 with Swift 3在 Xcode 8 和 Swift 3 中寻找关于修改后的 NSPersistentContainer 的清晰教程
【发布时间】:2017-01-27 21:43:56
【问题描述】:

我已经查看了 Apple 的:

Xcode 8 发行说明:
https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html

从 Swift 2.2 迁移到 Swift 2.3 或 Swift 3
https://swift.org/migration-guide/

macOS 10.12、iOS 10.0、tvOS 10.0 和 watchOS 3.0 中 Core Data 的新功能
https://developer.apple.com/library/content/releasenotes/General/WhatNewCoreData2016/ReleaseNotes.html#//apple_ref/doc/uid/TP40017342-CH1-DontLinkElementID_1

还有许多其他的……但应该从 Apple 获得的一份文档,即核心数据编程指南,尚未从 Swift 2 更新。
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/FetchingObjects.html#//apple_ref/doc/uid/TP40001075-CH6-SW1

理想情况下,我正在寻找类似的东西,但 Swift 3 除外。
https://www.raywenderlich.com/115695/getting-started-with-core-data-tutorial

任何线索将不胜感激。

根据 Tom 的评论(如下)我错过了哪一步?

1) 创建一个新项目“Test”

2) 选择使用 CoreDate(这会创建 Test.xcdatamodeld)

这将使用以下内容自动填充 AppDelegate(删除默认 cmets):

func applicationWillTerminate(_ application: UIApplication) {
self.saveContext()
}
lazy var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name: "Test")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()
func saveContext () {
    let context = persistentContainer.viewContext
    if context.hasChanges {
        do {
            try context.save()
        } catch {
            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

3) 创建实体“Foo”

4) 添加属性“bar”类型字符串

5) 在 ViewController.swift 下添加以下内容(这是从 Apple 复制的,我只是将“...use”替换为“print”)

func findAnimals() {
    let request: NSFetchRequest<Foo> = Foo.fetchRequest
    do {
        let searchResults = try context.fetch(request)
        print(searchResults)
    } catch {
        print("Error with request: \(error)")
    }
}

6) 在 override func viewDidLoad() 下添加 findAnimals()。

但是这有具体的错误:

  1. NSFetchRequest
  2. 上下文

7) 所以你返回并在 viewController 下的函数中添加一些 this 以使容器可访问(这不是 Apple 的示例表单)。

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

很好,我们清除了 2 个错误中的 1 个,但错误“使用未声明的类型 'NSFetchRequest'”仍然存在。

这就是我卡住的地方。即使查看了 Apple 发布的所有材料,我也找不到完整的示例。

【问题讨论】:

  • 具体有什么不明白的?
  • 有限的文档意味着只需在 xcdatamodeld 中创建一个实体,它将自动被识别。但是我不断收到“未解析的标识符”。
  • 你导入CoreData了吗?
  • 您可以在 lynda.com,Jonathan Bott 的“iOS 和 macOS 企业开发者的核心数据”课程中获得更多关于 Swift3 核心数据和并发性的信息
  • 这里有一些关于如何使用 dataController.managedObjectContext 获取上下文的 Apple 文档(如果您将 App 委托核心数据实现分离到 DataController 类中)。在视图中使用:developer.apple.com/library/content/documentation/Cocoa/… 分离到另一个类中:developer.apple.com/library/content/documentation/Cocoa/…

标签: ios core-data swift3 xcode8


【解决方案1】:

我仍然不能离开 cmets。所以让我把它放在这里。 相信这两个视频会对你有很大帮助。 Paul Hegarty 的斯坦福大学课程是最新的!

https://www.youtube.com/watch?v=ssIpdu73p7A - 关于CoreData的讲座 https://www.youtube.com/watch?v=whF63GTaW1w - 使用 CoreData 的演示。

【讨论】:

【解决方案2】:

据我了解,NSPersistentContainer 以一种简单的方式将主上下文和工作上下文解耦。可以简单地调用container.viewContext 进行任何UI 级别的数据访问(旧的NSMainQueueConcurrencyType),并使用container.newBackgroundContext 进行其他数据导入工作(旧的NSPrivtaeQueueConcurrencyType)。并且通过将automaticallyMergesChangesFromParent 设置为true 到任何上下文,它等于老听NSManagedObjectContextDidSaveNotification

参考:http://holko.pl/2016/06/23/core-data/

【讨论】:

    【解决方案3】:

    @Aaron 再次感谢您提供的视频链接,这让我走上了正轨。下面是 Xcode 8 中使用 Swift 3 从核心数据中获取、添加和清除核心数据所需的最低限度的快速演练。

    1. 新项目 > iOS 单视图应用程序
    2. 产品名称:“样品”
    3. 使用核心数据(选中)
    4. 保存
    5. 打开 Sample.xcdatamodeld
    6. 添加实体:“SampleEntity”
    7. 使用数据模型检查器将 Codegen(在 Class 下)设置为“Class Definition”
    8. 在新实体下创建一个属性:“sampleAttribute”
    9. 打开 ViewController.swift
    10. 在“import UIKit”下添加“import CoreData”
    11. 在类 ViewController 下添加以下内容:

      let context = (UIApplication.shared.delegate as!AppDelegate).persistentContainer.viewContext
      
      // 从他的属性中获取数据
      函数 getSample() {
          让请求:NSFetchRequest = SampleEntity.fetchRequest()
          request.resultType = NSFetchRequestResultType.dictionaryResultType
          做 {
              let searchResults = try context.fetch(request as!NSFetchRequest) as! [NS词典]
              让 searchResultsArray = searchResults.map { $0["sampleAttribute"] as!细绳}
              打印(“搜索结果数组”,搜索结果数组)
          } 抓住 {
              print("请求错误:\(error)")
          }
      }
      
      // 保存到属性
      函数集样本(){
          让 saveSample = SampleEntity(上下文:上下文)
          saveSample.sampleAttribute = "保存一个新字符串。"
          做 {
              尝试 context.save()
          } 抓住 {
               print("保存出错:\(error)")
          }
      }
      
      // 清除属性
      函数重置样本(){
          让 clearSample: NSFetchRequest = SampleEntity.fetchRequest()
          让 deleteResults = NSBatchDeleteRequest(fetchRequest: clearSample as! NSFetchRequest)
          做 {
              尝试 context.execute(deleteResults)
              尝试 context.save()
          } 抓住 {
              print("保存出错:\(error)")
          }
      }
    12. 在 override func viewDidLoad() 下添加以下内容:

      getSample()
      集合样本()
      获取样本()
      重置样本()
      getSample()
    13. 运行,你会在调试区看到如下打印:

      searchResultsArray [] // 初始属性为空
      searchResultsArray ["Save new string."] // 属性现在包含字符串
      searchResultsArray [] // 该属性已被清除

    【讨论】:

      【解决方案4】:

      可能是今年WWDC的视频What's New in Core Data可以给你更多内幕。

      大约在 31:20 分钟,他正在显示一些关于 NSFetchRequest 的代码。

      【讨论】:

      • 感谢您的链接!我观看了整个视频,引起我注意的是演示使用“主细节”模板而不是“单一视图”模板。在并排比较了两个太阳穴后,我注意到单视图模板的“代码生成”设置为“手动/无”,而不是新的自动“类定义”设置。更多精彩即将到来!
      猜你喜欢
      • 1970-01-01
      • 2021-03-17
      • 1970-01-01
      • 2016-12-19
      • 2015-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-20
      相关资源
      最近更新 更多