【问题标题】:SwiftUI: CoreData and complex JSONSwiftUI:CoreData 和复杂的 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

标签: json swift core-data


【解决方案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

【讨论】:

  • 非常感谢您的建议。我现在就试试!
猜你喜欢
  • 2014-04-12
  • 2018-12-14
  • 2020-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-10
  • 2021-08-15
相关资源
最近更新 更多