我正在尝试查询奇迹API。我认为我的可解码文件是错误的。我有以下代码:
struct ReturnedData : Decodable {
var id : Int?
var name : String?
var description : String?
}
var savedData : [ReturnedData] = []
let urlString = "https://gateway.marvel.com/v1/public/characters?ts=1&apikey=(myAPIKey)"
let url = URL(string: urlString)
let session = URLSession.shared
let dataTask = session.dataTask(with: url!) { (data, response, error) in
guard let data = data else {return}
do {
let recievedData = try JSONDecoder().decode([ReturnedData].self, from: data)
self.savedData = recievedData
} catch {
print(error)
}
}
dataTask.resume()
}
我收到以下错误消息:typeMismatch(Swift.Array,Swift.DecodingError.Context(codingPath:[],debugDescription:"应解码Array,但找到字典。"underlyingError:nil((
根据文件,我应该得到以下所有信息:字符
id(int,可选(:字符资源的唯一id。,name(字符串,可选(:字符的名称。描述(字符串,可选(:简短的个人简介或角色描述。修改(日期,可选(:最近修改资源的日期。resourceURI(字符串,可选(:此资源的规范URL标识符。urls(Array[Url],可选(:资源的一组公共网站Url。缩略图(图像,可选(:此角色的代表图像。漫画(漫画列表,可选(:包含此角色漫画的资源列表。故事(StoryList,可选(:出现此角色的故事的资源列表events(EventList,可选(:出现此字符的事件的资源列表。series(序列列表,可选(:出现此字符的序列的资源列表。
此外,任何关于如何获得缩略图的提示都将受到赞赏。
您得到的错误是因为您拥有的模型与json数据不匹配。因此,尝试这种方法...to query the marvel API...
。将来,将json数据复制并粘贴到https://app.quicktype.io/这将为您生成模型。根据需要调整生成的代码。或者阅读以下文档:https://developer.marvel.com/docs#/public/getCreatorCollection_get_0,并根据给定的信息手动创建模型。
class MarvelModel: ObservableObject {
@Published var results = [MarvelResult]()
let myAPIKey = "xxxx"
let myhash = "xxxx"
func getMarvels() async {
guard let url = URL(string: "https://gateway.marvel.com/v1/public/characters?ts=1&apikey=(myAPIKey)&hash=(myhash)") else { return }
do {
let (data, _) = try await URLSession.shared.data(from: url)
let response = try JSONDecoder().decode(MarvelResponse.self, from: data)
Task{@MainActor in
results = response.data.results
}
} catch {
print("---> error: (error)")
}
}
}
struct ContentView: View {
@StateObject var vm = MarvelModel()
var body: some View {
VStack {
if vm.results.isEmpty { ProgressView() }
List(vm.results) { item in
Text(item.name)
}
}
.task {
await vm.getMarvels()
}
}
}
struct MarvelResponse: Decodable {
let code: Int
let status, copyright, attributionText, attributionHTML: String
let etag: String
let data: MarvelData
}
struct MarvelData: Decodable {
let offset, limit, total, count: Int
let results: [MarvelResult]
}
struct MarvelResult: Identifiable, Decodable {
let id: Int
let name, resultDescription: String
let modified: String
let thumbnail: Thumbnail
let resourceURI: String
let comics, series: Comics
let stories: Stories
let events: Comics
let urls: [URLElement]
enum CodingKeys: String, CodingKey {
case id, name
case resultDescription = "description"
case modified, thumbnail, resourceURI, comics, series, stories, events, urls
}
}
struct Comics: Decodable {
let available: Int
let collectionURI: String
let items: [ComicsItem]
let returned: Int
}
struct ComicsItem: Identifiable, Decodable {
let id = UUID()
let resourceURI: String
let name: String
}
struct Stories: Decodable {
let available: Int
let collectionURI: String
let items: [StoriesItem]
let returned: Int
}
struct StoriesItem: Identifiable, Decodable {
let id = UUID()
let resourceURI: String
let name: String
let type: String
}
struct Thumbnail: Decodable {
let path: String
let thumbnailExtension: String
enum CodingKeys: String, CodingKey {
case path
case thumbnailExtension = "extension"
}
}
struct URLElement: Identifiable, Decodable {
let id = UUID()
let type: String
let url: String
}
第1版:如果你想要一些非常基本的东西,那么试试这个:
struct ContentView: View {
@State var results = [MarvelResult]()
var body: some View {
List(results) { item in
Text(item.name)
}
.onAppear {
getMarvels()
}
}
func getMarvels() {
let myAPIKey = "xxxx"
let myhash = "xxxx"
guard let url = URL(string: "https://gateway.marvel.com/v1/public/characters?ts=1&apikey=(myAPIKey)&hash=(myhash)") else { return }
URLSession.shared.dataTask(with: url) { (data, _, _) in
if let data = data {
do {
let response = try JSONDecoder().decode(MarvelResponse.self, from: data)
DispatchQueue.main.async {
self.results = response.data.results
}
}
catch {
print(error)
}
}
}.resume()
}
}