gpt4 book ai didi

Swift: 错误: keyNotFound(CodingKeys(stringValue: "adult", intValue: nil)

转载 作者:行者123 更新时间:2023-12-04 10:26:02 27 4
gpt4 key购买 nike

我确实在堆栈溢出中看到了很多类似的问题,但似乎没有人与我的情况相似。我是结合框架工作的新手,我花了一整个下午才弄清楚出了什么问题,但仍然停留在这里......

Xcode 给了我以下错误,我所做的是使用 TMDB 的 API 并将其解码为我的 Actor 模型。它在这条线上失败 let result = try self.decoder.decode(TMDBActorsResult.self, from: output.data) .你能给我一些提示吗 adult ?

ERROR: keyNotFound(CodingKeys(stringValue: "adult", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "results", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "knownFor", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"adult\", intValue: nil) (\"adult\").", underlyingError: nil))



我还检查了 url 是否正常工作,这是来自 TMDB API 的返回数据:

enter image description here

enter image description here

/// Actor 模型
import SwiftUI


struct TMDBActorsResult: Codable {
let page: Int?
let results: [Actor]
let totalResults: Int?
let totalPages: Int?
}

struct Actor: Codable {
let profilePath: String?
let adult: Bool
let id: Int?
let name: String?
let popularity: CGFloat?
let knownFor: [Production]?
let knownForDepartment: String?
let gender: Int?
}

// MARK: Used for two objects with media type = (Movie or TV)
struct Production: Codable {
let posterPath: String?
let adult: Bool
let overview: String?
let releaseDate: String?
let originalTitle: String?
let genreIds: [Int]?
let id: Int?
let mediaType: String?
let originalLanguage: String?
let title: String?
let backdropPath: String?
let popularity: Double?
let voteCount: Int?
let video: Bool
let voteAverage: Double?
let firstAirDate: String?
let originCountry: [String]?
let name: String?
let originalName: String?
}

///JSON解码部分。
import Foundation
import Combine

enum HTTPError: LocalizedError {
case statusCode
case post
}

struct WebService {

private var decoder: JSONDecoder = {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
return decoder
}()

private var session: URLSession = {
let config = URLSessionConfiguration.default
config.urlCache = URLCache.shared
config.waitsForConnectivity = true
config.requestCachePolicy = .reloadIgnoringLocalCacheData
return URLSession(configuration: config, delegate: nil, delegateQueue: nil)
}()

private func createPublisher<T: Codable>(for url: URL) -> AnyPublisher<T, Error> {
print("Pblisher URL: \(url)")
return session.dataTaskPublisher(for: url)
.tryMap { output in
guard let response = output.response as? HTTPURLResponse, response.statusCode == 200 else {
print("Response: \(output.response)")

do {
let ss = try self.decoder.decode(Response.self, from: output.data)
print("ss: \(ss)")
} catch {
print(error)
}
throw HTTPError.statusCode
}

do {
let result = try self.decoder.decode(TMDBActorsResult.self, from: output.data)
print("Result: \(result)")
} catch {
print("ERROR: \(error)")
}
return output.data
}
.decode(type: T.self, decoder: decoder)
.eraseToAnyPublisher()
}

func getSectionsPublisher() -> AnyPublisher<TMDBActorsResult, Error> {
createPublisher(for: TMDBClient.Endpoints.popularActors.url).eraseToAnyPublisher()
}

}



/// 更新,作为瓦迪安的评论,我尝试将我的数据模型修改为使用枚举关联值,如下面的代码所示,但它给了我错误 Instance method 'decode(_:forKey:)' requires that 'MediaType' conform to 'Decodable' .我发布说不同的是我的模型正在使用 type在项目中,但不在根媒体结构中。
let jsonString = """
[{"name": "Popular Movies",
"description": "Basic movie description",
"items": [ { "id": 15, "budget": 10, "type": "movies","name": "Sample movie", "movieSPT": ""}]
},
{"name": "Popular TV Shows",
"description": "Basic shows description",
"items": [ { "id": 15, "adult": false, "type": "tvshows","title": "Sample show", "showSPT": ""}]
}
]
"""
let data = Data(jsonString.utf8)


struct Movie : Decodable {
let id: Int
let name, movieSPT: String
let type: String
let budget: Int
}

struct TVShow : Decodable {
let id: Int
let title, showSPT: String
let type: String
let adult: Bool
}

enum MediaType {
case movie([Movie]), tvShow([TVShow])
}

struct Media : Decodable {
let name : String
let description : String
let items : MediaType

private enum CodingKeys : String, CodingKey { case name, description, type, items }

init(from decoder : Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
self.description = try container.decode(String.self, forKey: .description)
self.items = try container.decode(MediaType.self, forKey: .items)
// type = try container.decode(String.self, forKey: .type)
if items.type == "movies" {
let movieData = try container.decode([Movie].self, forKey: .items)
// print("AAA: \(movieData)")
items = .movie(movieData)
} else { // add better error handling
let showData = try container.decode([TVShow].self, forKey: .items)
items = .tvShow(showData)
}

}
}

do {
let result = try JSONDecoder().decode([Media].self, from: data)
print(result)
} catch {
print(error)
}

添加 JSON 数据 , known_for是一个[对象],该对象可以是电影类型或电视类型。
{
"page": 1,
"total_results": 10000,
"total_pages": 500,
"results": [
{
"popularity": 57.168,
"known_for_department": "Acting",
"name": "Thassapak Hsu",
"id": 1910848,
"profile_path": "/1fmjgN8EvDj1TiEJk2Zs4y0T40O.jpg",
"adult": false,
"known_for": [
{
"original_name": "萌妻食神",
"genre_ids": [
35,
10765,
10766
],
"media_type": "tv",
"name": "Cinderella Chef",
"origin_country": [],
"vote_count": 5,
"first_air_date": "2018-04-23",
"backdrop_path": "/rnzmWKEiWPb8GC1mlqQojj8ccWj.jpg",
"original_language": "zh",
"id": 79574,
"vote_average": 9,
"overview": "",
"poster_path": "/xb40Li6ff1BK0pVOxV4lutssCrR.jpg"
},
{
"original_name": "外星女生柴小七",
"genre_ids": [
35,
10765
],
"media_type": "tv",
"name": "My Girlfriend is an Alien",
"origin_country": [
"CN"
],
"vote_count": 2,
"first_air_date": "2019-08-19",
"backdrop_path": "/kCl7piWv3pypgYfyLFi7ZgFGlYV.jpg",
"original_language": "zh",
"id": 92779,
"vote_average": 9,
"overview": "The alien girl Chai Xiaoqi tells the story of Fang Xiaoqi, the overbearing president of the alien girl who died from the \"Cape Town Planet\", who was suffering from the \"rainy weather heterosexual amnesia\". A high-energy hilarious and romantic cross-star love story. The female host Chai Xiaoqi is not only an alien, but also a true-handed witch. Once she inhales the hormones emitted by the males in the earth, she will fall into the \"flowery state\" and suffer from various diseases. The fun and ridiculously ridiculous romance will restore the singularity of the girl in the perfection of the girl. In order to survive on the human earth, Chai Xiaoqi will use his various super powers to solve one accident after another, like a roller coaster. The ups and downs will make the audience hooked. The male lord is cold and is an alternative overbearing president. When it rains, he will forget the opposite sex that appears around him. For this reason, he and the female host will launch various \"fighting and fighting\" laughter dramas. The experience of high sweetness and romance is expected to be Strongly slammed the girl's heart when it was broadcast.",
"poster_path": "/5e2owvs9TWVsuIacTFxJGPp6KVW.jpg"
},
{
"original_name": "Devil Lover เผลอใจ..ให้นายปีศาจ",
"id": 74640,
"media_type": "tv",
"name": "Devil Lover เผลอใจ..ให้นายปีศาจ",
"vote_count": 0,
"vote_average": 0,
"first_air_date": "2015-10-07",
"poster_path": "/moThN7iERydEHI2RbfrmhCp69R4.jpg",
"genre_ids": [
35
],
"original_language": "th",
"backdrop_path": "/iRYOwW6DRIRwDYVmRWA8nbfaV2c.jpg",
"overview": "",
"origin_country": [
"TH"
]
}
],
"gender": 2
},
{
"popularity": 39.35,
"known_for_department": "Acting",
"gender": 1,
"id": 2487703,
"profile_path": "/jRdDoFoHq36hg4kYxxiLa5DRYUW.jpg",
"adult": false,
"known_for": [
{
"poster_path": "/d9PhCnofBEeQGR3lwywTjWKBiXj.jpg",
"id": 449924,
"vote_count": 346,
"video": false,
"media_type": "movie",
"adult": false,
"backdrop_path": "/ekP6EVxL81lZ4ivcqPsoZ72rY0h.jpg",
"genre_ids": [
28,
18,
36
],
"original_title": "葉問4",
"original_language": "cn",
"title": "Ip Man 4: The Finale",
"vote_average": 6,
"overview": "Following the death of his wife, Ip Man travels to San Francisco to ease tensions between the local kung fu masters and his star student, Bruce Lee, while searching for a better future for his son.",
"release_date": "2019-12-20"
}
],
"name": "Vanda Lee"
},
{
"popularity": 28.664,
"known_for_department": "Acting",
"gender": 1,
"id": 556435,
"profile_path": "/5MgWM8pkUiYkj9MEaEpO0Ir1FD9.jpg",
"adult": false,
"known_for": [
{
"release_date": "2019-05-30",
"id": 496243,
"vote_count": 5120,
"video": false,
"media_type": "movie",
"vote_average": 8.6,
"title": "Parasite",
"genre_ids": [
35,
18,
53
],
"original_title": "기생충",
"original_language": "ko",
"adult": false,
"backdrop_path": "/TU9NIjwzjoKPwQHoHshkFcQUCG.jpg",
"overview": "All unemployed, Ki-taek's family takes peculiar interest in the wealthy and glamorous Parks for their livelihood until they get entangled in an unexpected incident.",
"poster_path": "/7IiTTgloJzvGI1TAYymCfbfl3vT.jpg"
},
....

最佳答案

错误说:

adult 没有值在数组 Index 0 的第一项( knownFor )中( [Production] ) 位于数组 Index 0 的第一项 ( results ) 中( Actor )。

请检查,屏幕截图仅显示 [...]
关于您的编辑:

你不能那样解码嵌套字典,请试试这个

struct TMDBActorsResult: Decodable {
let page: Int
let results: [Actor]
let totalResults: Int
let totalPages: Int
}

struct Actor: Decodable {
let popularity: Double
let knownForDepartment: String
let gender: Int
let profilePath: String
let name: String?
let id: Int
let adult: Bool
let knownFor: [Production]
}

enum MediaType : String, Decodable {
case tv, movie
}

// MARK: Used for two objects with media type = (Movie or TV)
enum Production : Decodable {
case movie(Movie), tvShow(TVShow)

private enum CodingKeys : String, CodingKey { case mediaType }

init(from decoder : Decoder) throws {
let dictionaryContainer = try decoder.container(keyedBy: CodingKeys.self)
let mediaType = try dictionaryContainer.decode(MediaType.self, forKey: .mediaType)
let container = try decoder.singleValueContainer()
switch mediaType {
case .tv: self = .tvShow(try container.decode(TVShow.self))
case .movie: self = .movie(try container.decode(Movie.self))
}
}
}

struct Movie: Decodable {
let posterPath: String
let adult: Bool
let voteCount: Int
let video: Bool
let backdropPath: String
let genreIds: [Int]
let originalTitle: String
let originalLanguage: String
let title: String
let voteAverage: Double
let overview: String
let releaseDate: String
}

struct TVShow: Decodable {
let originalName: String
let genreIds: [Int]
let name: String
let originCountry: [String]
let backdropPath: String
let voteCount: Int
let firstAirDate: String
let originalLanguage: String
let overview: String
let posterPath: String
let id: Int
}

关于Swift: 错误: keyNotFound(CodingKeys(stringValue: "adult", intValue: nil),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60633154/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com