SwiftUI:CoreData 和复杂的 JSON

Posted

技术标签:

【中文标题】SwiftUI:CoreData 和复杂的 JSON【英文标题】:SwiftUI: CoreData and complex JSON 【发布时间】:2020-09-08 19:45:52 【问题描述】:

我正在尝试将 JSON 保存到 CoreData,但 JSON 有点复杂,包含许多数组对象。我只能保存和显示简单的属性,如 String、Int... 但如果我添加具有可转换类型的属性,如 [Currency]、[Double],应用程序将崩溃。

您能告诉我正确的实现方法吗?

我的数据模型

struct Currency: Decodable 
    let code, name, symbol: String?


struct Language : Decodable 
    let name : String?


struct WorldData: Identifiable, Decodable 
    var id : Int 
        return population
    
    var name : String?
    ...
    var latlng : [Double]?
    var currencies : [Currency]?
    var languages : [Language]
    ...

我的手动 NSManagedObject 子类

extension CDCountry 

    @nonobjc public class func fetchRequest() -> NSFetchRequest<CDCountry> 
        return NSFetchRequest<CDCountry>(entityName: "CDCountry")
    

    @NSManaged public var name: String?
    @NSManaged public var latlng: NSObject?
    @NSManaged public var currencies: NSObject?
    @NSManaged public var languages: NSObject?
    ...

    public var wrapperLatlng : NSObject 
        latlng ?? ["Unknown error"] as NSObject
    
    
    public var wrapperCurrencies : NSObject 
        currencies ?? ["Unknown error"] as NSObject
    
...

以及我如何将加载的 JSOn 保存到 CoreData

static func loadDataToCD(moc: NSManagedObjectContext) 
        loadDataFromJSON  (countries) in
            DispatchQueue.main.async 
                var tempCountries = [CDCountry]()
                for country in countries 
                    let newCountry = CDCountry(context: moc)
                    
                    ...
                    newCountry.currencies  = country.currencies as NSObject?
                    newCountry.languages = country.languages as NSObject
                    newCountry.latlng = country.latlng as NSObject?
                    newCountry.name = country.name
                    ...
                    tempCountries.append(newCountry)
                
                do 
                    try moc.save()
                 catch let error 
                    print("Could not save to CD: ", error.localizedDescription)
                
            

【问题讨论】:

您使用的是Codable,但可转换属性需要NSCoding。这些协议做类似的事情,但不兼容。 Codable 类型不能与可转换属性一起使用。 您对如何使其兼容有什么建议吗?谢谢@Tom Harrington 【参考方案1】:

没有简单的方法来回答您的问题,但我可以为您指出一些资源。

在 Apple 为 SwiftUI 提供的“处理用户输入”教程中包含的 Landmark.swift 文件中有一个很好的解码 JSON 的示例。这可能有助于基础知识。 https://developer.apple.com/tutorials/swiftui/handling-user-input

本教程使用自定义的 CoordinatesCategory 类,这些类很可能模仿您的 CurrencyLanguage 对象的过程。但当然,这将是一个非托管对象。

要做到托管,最好为CurrencyLanguage 创建CoreData 对象,并将它们作为relationship 加入CoreData,而不是让它们成为Transformable

然后您可以按照这个老问题的答案进行非常彻底的回答Save complex JSON to Core Data in Swift

你也可以看看这个问题Swift And CoreData With Custom Class As Transformable Object

【讨论】:

非常感谢您的建议。我现在就试试!

以上是关于SwiftUI:CoreData 和复杂的 JSON的主要内容,如果未能解决你的问题,请参考以下文章

使用 SwiftUI 和 CoreData 的数据

@State 和 CoreData 的 SwiftUI 预览问题

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

在 CoreData 记录中进行更改,SwiftUI

如果没有数据,带有 @FetchRequest (SwiftUI) 和 NSPredicate 的 CoreData 会崩溃

SwiftUI 如何使 CoreData 列表在 macOS 上可选择和可双击