проблема сохранения объектов Entity из строки JSON - как наследовать от кодируемых? - PullRequest
0 голосов
/ 25 апреля 2019

Я получил строку json из API фильма.Прямо сейчас я держу 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 голосов
/ 25 апреля 2019

Объявите вашу структуру:

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)
    }
0 голосов
/ 25 апреля 2019

Возможно, вам следует создать модель данных, соответствующую 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 (). Декодирует броски.Для отладки очень полезно напечатать ошибку в предложении catch.

catch let error {
    print(error)
}
...