从json字符串保存实体对象时出现问题-如何从可编码继承?

时间:2019-04-25 09:42:44

标签: swift iphone core-data datapersistance

我已经从电影API中获取了json字符串。现在,我将JSON放在String对象中,并且我想迭代地将所有json扔掉并创建对象以填充它们的数组。 事实是,我要创建的对象已生成Core Data,但我找不到任何从超类继承实体的方法。

override func viewDidLoad() {
    super.viewDidLoad()

    httpRequest(urlForRequest: base_url) { (data: Data?, error: Error?) in
        if error == nil {
            if let moviesData = data {
                guard let jsonString = String(data: moviesData, encoding: String.Encoding.utf8) else {return}

            }
        } else {
            print(error?.localizedDescription ?? "error with no description")
        }
    }

}

现在我如何有效地迭代抛出这个jsonString并创建一个新的实体对象?

我想复制吗?

这是我的实体:

enter image description here

2 个答案:

答案 0 :(得分:0)

也许您应该创建一个符合Codable的数据模型(由于它包含Encodable和Decodable这两个协议,而不是一个类,所以您不能继承它)。将JSON解码为对象后,您可以按任意方式将其映射到核心数据。

struct MovieData: Codable {
  var genre: String
  var title: String
  ...
}

请注意使用与JSON中的键完全相同的变量名,然后它将像魔术一样工作。否则,您可以使用CodingKeys枚举来定义键。

enum CodingKeys: String, CodingKey {
case title = "movie_title" // define the coding key: string pairs that don't match the json
case id, rating, genre...// list all keys that match the json

}

要解码json,请使用

JSONDecoder().decode([MovieModel].self, from: data)

数据是响应中的原始数据。如果您具有更复杂的结构,则将其分解,例如,如果每个MovieModel的属性都是对象数组,则为这些对象创建一个单独的结构(当然,它符合可编码),并且应像魅力一样工作。不要忘记JSONDecoder()。decode抛出。在catch子句中打印错误以进行调试非常有用。

catch let error {
    print(error)
}

答案 1 :(得分:0)

声明您的结构:

struct MyStruct : Codable {
    var title : String
    var image : String
    var rating : Float
    var releaseYear : Int
    var genre : [String]?
}

将您的代码重新设置为以下代码之一:

   httpRequest(urlForRequest: base_url) { (data: Data?, error: Error?) in
            if error == nil {
                if let moviesData = data {
                    guard let jsonString = String(data: moviesData, encoding: .utf8) else {return}
                    do {
                        guard let json = try JSONSerialization.jsonObject(with: moviesData) as? [Any] else {return}
                        let jsonData = try JSONSerialization.data(withJSONObject: json)
                        let array = try JSONDecoder().decode([MyStruct].self, from: jsonData) as [MyStruct]
                        print(array)
                        print(array[0])
                        // handle your array with `CoreData` values.
                    } catch {
                        print(error)
                    }
                }
            } else {
                print(error?.localizedDescription ?? "error with no description")
            }
        }

在这里处理您的示例:

    let r = """
    [{ "title": "District 9", "image": "api.androidhive.info/json/movies/2.jpg", "rating": 8, "releaseYear": 2009, "genre": ["Action", "Sci-Fi", "Thriller"] }, { "title": "How to Train Your Dragon", "image": "api.androidhive.info/json/movies/15.jpg", "rating": 8.2, "releaseYear": 2010, "genre": ["Animation", "Adventure", "Family"]}]
    """
    do {
        let data = r.data(using: .utf8)
        guard let json = try JSONSerialization.jsonObject(with: data ?? Data()) as? [Any] else {return}
        let jsonData = try JSONSerialization.data(withJSONObject: json)
        let array = try JSONDecoder().decode([MyStruct].self, from: jsonData) as [MyStruct]
        print(array)
        print(array[0])
    } catch {
        print(error)
    }