JSON 解码时出错:Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "cast", intValue: nil)
Error while JSON decoding: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "cast", intValue: nil)
在尝试解码 JSON 时,我 运行 出现错误:
Fatal error: 'try!' expression unexpectedly raised an error:
Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "cast",
intValue: nil), Swift.DecodingError.Context(codingPath: [],
debugDescription: "No value associated with key
CodingKeys(stringValue: "cast", intValue: nil) ("cast").",
underlyingError: nil))
什么是st运行ge,不是每次都会出现,我打开MovieDetailsView
几次都可以不报错,但是出现的次数更多。可能是什么问题?
数据模型:
struct MovieCreditResponse: Codable {
let cast: [MovieCast]
}
struct MovieCast: Identifiable, Codable {
let id: Int
let character: String
let name: String
let profilePath: String?
}
这里我取数据:
class TMDbApi {
//...
func getMovieCredits(movieID: String, completion:@escaping (MovieCreditResponse) -> ()){
guard let url = URL(string: "https://api.themoviedb.org/3/movie/\(movieID)/credits?api_key=<api_key>") else { return }
URLSession.shared.dataTask(with: url) { (data, _, _) in
let movies = try! JSONDecoder().decode(MovieCreditResponse.self, from: data!) //ERROR IS HERE
DispatchQueue.main.async {
completion(movies)
}
}
.resume()
}
}
MovieDetailsView:
struct MovieDetailsView: View {
var movie: Movie
@State var casts: [MovieCast] = []
var body: some View {
VStack{
MoviePosterView(posterPath: movie.posterPath!)
List{
ForEach(casts){ cast in
Text(cast.name)
}
}
}.onAppear{
TMDbApi().getMovieCredits(movieID: movie.id.uuidString){ data in
self.casts = data.cast
}
}
}
}
内容视图:
struct ContentView: View {
@State var movies: [Movie] = []
var body: some View {
NavigationView{
List {
ForEach(movies) { movie in
NavigationLink(destination: MovieDetailsView(movie: movie)){
//...
}
}
}.onAppear(){
TMDbApi().getMovies{ data in
self.movies = data.results
}
//...
}
.navigationTitle("Movies App")
}
}
}
如果您的响应可能包含错误(错误确实会发生!),您的应用应该知道并处理它。
struct MovieCreditResponse: Codable {
let success : Bool
let status_code : Int
let status_message : String?
let cast: [MovieCast]?
}
然后当您收到回复时,检查是否成功并让您的应用处理错误:
do {
guard let d = data else {
// handle null data error
}
let responseObject = try JSONDecoder().decode(MovieCreditResponse.self, from: d)
if responseObject.success {
guard let cast = responseObject.cast as? [MovieCast] else {
// handle error of null cast here
}
// this is the happy path: do your thing
} else {
if let errorMessage = responseObject.status_message {
// handle the case of an identified error
handleError(errorMessage)
} else {
// handle the case where something went wrong and you don't know what
}
}
} catch {
// handle decoding error here
}
终于找到错误原因了。我在电影模型中使用 UUID
类型而不是 Int
来表示 id
属性(这是我在 URL 中用来查询电影演员表的 ID)。因此,在我的请求中,电影 ID 的格式为“F77A9A5D-1D89-4740-9B0D-CB04E75041C5”,而不是“278”。有趣的是,有时这并没有导致错误,这让我感到困惑(我仍然不知道为什么有时会这样)
所以,我替换了
struct Movie: Identifiable, Codable{
let id = UUID()
//...
}
和
struct Movie: Identifiable, Codable{
let id: Int
//...
}
感谢所有帮助我找到解决方案的人
在尝试解码 JSON 时,我 运行 出现错误:
Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "cast", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: "cast", intValue: nil) ("cast").", underlyingError: nil))
什么是st运行ge,不是每次都会出现,我打开MovieDetailsView
几次都可以不报错,但是出现的次数更多。可能是什么问题?
数据模型:
struct MovieCreditResponse: Codable {
let cast: [MovieCast]
}
struct MovieCast: Identifiable, Codable {
let id: Int
let character: String
let name: String
let profilePath: String?
}
这里我取数据:
class TMDbApi {
//...
func getMovieCredits(movieID: String, completion:@escaping (MovieCreditResponse) -> ()){
guard let url = URL(string: "https://api.themoviedb.org/3/movie/\(movieID)/credits?api_key=<api_key>") else { return }
URLSession.shared.dataTask(with: url) { (data, _, _) in
let movies = try! JSONDecoder().decode(MovieCreditResponse.self, from: data!) //ERROR IS HERE
DispatchQueue.main.async {
completion(movies)
}
}
.resume()
}
}
MovieDetailsView:
struct MovieDetailsView: View {
var movie: Movie
@State var casts: [MovieCast] = []
var body: some View {
VStack{
MoviePosterView(posterPath: movie.posterPath!)
List{
ForEach(casts){ cast in
Text(cast.name)
}
}
}.onAppear{
TMDbApi().getMovieCredits(movieID: movie.id.uuidString){ data in
self.casts = data.cast
}
}
}
}
内容视图:
struct ContentView: View {
@State var movies: [Movie] = []
var body: some View {
NavigationView{
List {
ForEach(movies) { movie in
NavigationLink(destination: MovieDetailsView(movie: movie)){
//...
}
}
}.onAppear(){
TMDbApi().getMovies{ data in
self.movies = data.results
}
//...
}
.navigationTitle("Movies App")
}
}
}
如果您的响应可能包含错误(错误确实会发生!),您的应用应该知道并处理它。
struct MovieCreditResponse: Codable {
let success : Bool
let status_code : Int
let status_message : String?
let cast: [MovieCast]?
}
然后当您收到回复时,检查是否成功并让您的应用处理错误:
do {
guard let d = data else {
// handle null data error
}
let responseObject = try JSONDecoder().decode(MovieCreditResponse.self, from: d)
if responseObject.success {
guard let cast = responseObject.cast as? [MovieCast] else {
// handle error of null cast here
}
// this is the happy path: do your thing
} else {
if let errorMessage = responseObject.status_message {
// handle the case of an identified error
handleError(errorMessage)
} else {
// handle the case where something went wrong and you don't know what
}
}
} catch {
// handle decoding error here
}
终于找到错误原因了。我在电影模型中使用 UUID
类型而不是 Int
来表示 id
属性(这是我在 URL 中用来查询电影演员表的 ID)。因此,在我的请求中,电影 ID 的格式为“F77A9A5D-1D89-4740-9B0D-CB04E75041C5”,而不是“278”。有趣的是,有时这并没有导致错误,这让我感到困惑(我仍然不知道为什么有时会这样)
所以,我替换了
struct Movie: Identifiable, Codable{
let id = UUID()
//...
}
和
struct Movie: Identifiable, Codable{
let id: Int
//...
}
感谢所有帮助我找到解决方案的人