Я пытаюсь создать приложение, чтобы научиться использовать дженерики в Swift.Поэтому я решил использовать API Studio Ghibli
. Для этого я делаю следующее:
- Создайте запрос к API
- Получитьответ
- Разбор JSON
Как и в их API, вся информация поставляется с baseURL
, равным https://ghibliapi.herokuapp.com
, и все конечные точки baseURL/foo
и возвращаютмассив любой информации, которую мы хотим.Итак, для этого конкретного случая я пытаюсь использовать /films
и /people
.
Так что, в моей голове, было бы лучше иметь универсальную функцию декодирования, которая делает это и возвращает массивсоответствующего класса, который мы хотим декодировать.
private func decode<T: Decodable>(json: Data, as clazz: T) {
do {
let decoder = JSONDecoder()
let films = try decoder.decode([T].self, from: json)
} catch {
print("An error occurred while parsing JSON")
}
}
И я называю его так:
self.decode(json: safeData, as: Films.self) //Error thrown here
Мой класс Films
выглядит следующим образом:
import Foundation
import CoreData
@objc(Films)
public class Films: NSManagedObject, Decodable {
enum CodingKeys: String, CodingKey {
case id
case title
case film_description = "description"
case director
case producer
case release_date
case rt_score
}
required public init(from decoder: Decoder) throws {
guard let context = CodingUserInfoKey(rawValue: "context"),
let managedObjectContext = decoder.userInfo[context] as? NSManagedObjectContext,
let entity = NSEntityDescription.entity(forEntityName: "Films", in: managedObjectContext) else {
fatalError("Failed to decode Films!")
}
super.init(entity: entity, insertInto: nil)
let container = try decoder.container(keyedBy: CodingKeys.self)
do {
id = try container.decodeIfPresent(String.self, forKey: .id)
title = try container.decodeIfPresent(String.self, forKey: .title)
film_description = try container.decodeIfPresent(String.self, forKey: .film_description)
director = try container.decodeIfPresent(String.self, forKey: .director)
producer = try container.decodeIfPresent(String.self, forKey: .producer)
release_date = try container.decodeIfPresent(String.self, forKey: .release_date)
rt_score = try container.decodeIfPresent(String.self, forKey: .rt_score)
} catch let error {
print(error)
throw error
}
}
}
Но я получаю сообщение об ошибке:
Argument type 'Films.Type' does not conform to expected type 'Decodable'
Я прочитал на форумах Swift следующие темы:
И некоторые говорили, что эти решения сработалидля них, но это та же концепция, что и у меня, и я до сих пор не могу понять, как ее решить.
Как правильно это сделать?