如何快速将核心数据托管对象数组转换为“可识别”列表? (Xcode 11,测试版 5)

Posted

技术标签:

【中文标题】如何快速将核心数据托管对象数组转换为“可识别”列表? (Xcode 11,测试版 5)【英文标题】:How to transform array of core data managed objects into an "identifiable" list, in swift? (Xcode 11, Beta 5) 【发布时间】:2019-08-08 04:58:43 【问题描述】:

如何将使用 Swift/ios 通过“fetchRequest”从 Core Data 检索到的托管对象数组传输到“可识别”数组?

示例 - 如何使“任务”数组“可识别”

let fetchRequest : NSFetchRequest<Todo> = Todo.fetchRequest()
let tasks = try context?.fetch(fetchRequest)

背景:

在使用“列表”的 SwiftUI 中,您传递给列表的数据数组必须是“可识别的”。 我还注意到,identified(by: .self) 似乎已被弃用。 使用(Xcode 11,Beta 5) 目前使用 xcode 为核心数据实体自动创建托管对象,所以最好坚持这种方法

【问题讨论】:

【参考方案1】:

使用替换ForEach(Data, id: \.idAttribute)

identified(by: .self) 功能已被新语法替换:

ForEach(filteredGrapes, id: \.id)  grape in
    GrapeCell(grape: grape)

核心数据示例:

使用名为 ItemStore.xcdatamodeld 的文件和定义为启用 Generation=Class Definition 的实体 ItemDAO 并具有名为 title 的字符串属性。

注意:必须Product/Clear Build Folder然后重启Xcode才能使Xcode11Beta5找到正确的密钥路径,这似乎是Xcode11Beta5中的一个错误。

import Foundation
import SwiftUI
import CoreData

class MyItemStore 
    public static func defaultItems() -> [ItemDAO]
        let store = NSPersistentContainer(name: "ItemStore")
        store.loadPersistentStores  (desc, err) in
            if let err = err 
                fatalError("core data error: \(err)")
            
        
        let context = store.viewContext
        let item = ItemDAO(context: context)
        item.title = "hello you"
        try! context.save()
        return [
            item,
            item,
        ]
    


struct CoreDataView: View 
    let items: [ItemDAO] = MyItemStore.defaultItems()

    var body: some View 
        VStack
            ForEach(items, id: \.title)  (item: ItemDAO) in
                Text(item.title ?? "no title")
            
            Text("hi")
        
    

通过扩展添加可识别

extension Todo: Identifiable 
    public var id: String 
        //return self.objectID.uriRepresentation().absoluteString
        return self.title!
    

手动维护CoreData模型添加Identifiable

在那里你可以像往常一样添加Identifiable,虽然这不是必需的,因为扩展也可以添加 Identifiable。

【讨论】:

我刚刚用一个核心数据实体尝试了这个概念,它只有一个属性“title”,一个字符串,所以我有“id: \.title”,但是我得到一个构建错误:“类型'_'没有成员'标题'”。 (有问题的行:“ForEach(todoStore.getTodoItems(), id: \.title) item in”) @Greg 添加了一个示例。您可能必须重新启动 Xcode 才能找到关键路径,这听起来像是一个错误。 只是尝试了这个,但没有帮助 - 几乎就像它无法从自动生成的(我不能在我的 xcode 项目中)获取“标题”属性一样 Todo 管理从我的核心数据模型创建的对象...(?) 知道了——我改为手动创建托管子类,并在这里看到 xcode 将“title”属性设为可选,尽管在 coredata 设计器中它不是......它现在正在接受“title”属性没问题 现在可以正常使用了。我认为它更类似于 Xcode 错误,因为我必须清除构建文件夹,然后重新启动 Xcode 才能正确获取密钥路径。这种方式类定义生成也适用于我。

以上是关于如何快速将核心数据托管对象数组转换为“可识别”列表? (Xcode 11,测试版 5)的主要内容,如果未能解决你的问题,请参考以下文章

将二维数组转换为列表(一维)的快速方法

为啥核心数据托管对象中的 NSDate 转换为 NSTimeInterval?

如何将树状的数组和对象的嵌套数据结构转换为具有计算/计数 id 和跟踪父 id 的项目列表?

如何将对象列表转换为对象列表数组,每个数组索引都有 2 个计数?

如何迭代对象数组或将对象列表转换为数组?

如何将带有数组的对象转换为数组