使用泛型和Decodeable解码JSON数组



我正在尝试制作一个应用程序,以便学习如何在Swift中使用泛型。所以我决定使用吉卜力工作室的API

为此,我做了以下操作:

  1. 创建对API的请求
  2. 获取响应
  3. 解析JSON

在他们的API中,所有信息都带有等于https://ghibliapi.herokuapp.combaseURL,所有端点都是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论坛上读到了以下主题:

  • 将可解码对象作为泛型参数传递,这帮助我将Decodable放置在函数中
  • 如何在Swift 4中引用通用的可解码结构

有些人说这些解决方案对他们有效,但这与我的概念相同,我仍然不知道如何解决。

正确的方法是什么?

解决方案非常简单:

此功能:

private func decode<T: Decodable>(json: Data, as clazz: T) {

名称:

private func decode<T: Decodable>(json: Data, as clazz: T.Type) {

就这样!这就是所需要做的一切

相关内容

  • 没有找到相关文章

最新更新