0

我从电影 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并创建一个新的实体对象?

我想复制?

这是我的实体:

在此处输入图像描述

4

2 回答 2

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)
    }
于 2019-04-25T10:30:55.897 回答
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)

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

catch let error {
    print(error)
}
于 2019-04-25T10:16:37.593 回答