Swiftui中CoreData关系和显示图像列表

Posted

技术标签:

【中文标题】Swiftui中CoreData关系和显示图像列表【英文标题】:CoreData Relationship and Show the list of image in Swiftui 【发布时间】:2021-03-04 07:26:36 【问题描述】:

我尝试使用实体关系在 CoreData 中存储图像列表。

模型设计如下:

添加数据时,我尝试编写如下代码:

let imageData1 = UIImage(imageLiteralResourceName: "Dummy1").jpegData(compressionQuality: 1)
let imageData2 = UIImage(imageLiteralResourceName: "Dummy2").jpegData(compressionQuality: 1)
                
newItem.addToItemImages(NSSet(array: [imageData1!, imageData2!]))
                    
try? self.viewContext.save()

之后,我想通过 SwiftUI 检索它们,但我没有这样做:

    ForEach(Array(self.item.itemImages! as! Set), id:\.self) image in
            Image(uiImage: image)
                .frame(width: 300, height: 300)
        

它抱怨无法在当前上下文中推断“图像”的类型。

我的问题在这里:

    在 CoreData 中存储图像序列的正确方法是什么。这是我目前的方法好吗?我目前的方法是 1(项目)对多(ItemImage)关系。 ItemImage 有一个名为“image”的字段,它是二进制数据类型。

    这是我正确存储 ItemImage 的方法吗?

    如何从item中获取所有ItemImage(NSSet),然后使用Swiftui的Image()显示?

【问题讨论】:

【参考方案1】:

您的实体似乎设置正常;我只会将Item 实体中itemImages 关系的Delete Rule 更改为Cascade,以避免数据库中出现孤立的ItemImages。

要添加图像,您需要先创建ItemImage 的实例,然后将关系设置为Item。这可以在一个块中完成,如下所示:

if let imageData = UIImage(named: "Dummy1")?.jpegData(compressionQuality: 0.85) 
    let image = ItemImage(context: moc)
    image.id = UUID()
    image.image = imageData
    image.ofItem = item

由于两个不同的原因,您检索图像的尝试无效:

首先:编译器不知道item.itemImagesItemImage 的集合。自动生成的代码将 itemImages 声明为

@NSManaged public var itemImages: NSSet?

因此,您需要在代码中通过转换为 Set<ItemImage> 而不是简单地转换为 Set 来提供此信息。您可以通过将itemImages 的声明更改为:

@NSManaged public var itemImages: Set<ItemImage>?

第二:你的集合的元素类型是ItemImage(而不是UIImage),所以在你的代码中你需要调用Image(uiImage: UIImage(data: image.image!)!)来创建一个Image(即从ItemImage 对象的 image 属性中包含的数据)。更新后的代码(保留许多我个人不会在我自己的代码中使用的强制解包)如下所示:

ForEach(Array(item.itemImages! as! Set<ItemImage>))  image in
    Image(uiImage: UIImage(data: image.image!)!)
        .resizable()
        .aspectRatio(contentMode: .fit)
        .frame(maxWidth: 300, maxHeight: 300)

如果您如上所述更改itemImages 的声明,则可以简化为

ForEach(Array(item.itemImages!))  image in
    ...

【讨论】:

【参考方案2】:

您必须首先创建ItemImage 类型的记录,并将图像分配给每个记录的image 属性。然后您可以使用生成的addToItemImages 函数将这些记录添加到Item 记录的itemImages 关系中。

【讨论】:

以上是关于Swiftui中CoreData关系和显示图像列表的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 2.0列表项层级缩进显示CoreData托管数据的3种实现

在 SwiftUI 中显示来自 CoreData 的图像

浅谈CoreData海量数据(实时动态添加和删除)在SwiftUI列表中分页显示的原理及实现

使用 ForEach SwiftUI Core Data 仅更改列表中的一项

过滤后的 SwiftUI CoreData 列表中的 Sum 属性

SwiftUI - 如何在 CoreData 中删除实体中的行