为什么 JSONDecoder 对于可选的 属性 总是 returns nil?

Why JSONDecoder always returns nil for an optional property?

我得到 JSON 其中一个键可以是 nil。所以,我在数据模型中使用了一个可选的 属性,但是在解码之后,我总是得到 nil 这个 属性,即使在 JSON 中,键值包含一个字符串而不是 nil。下面是我得到的响应和控制台的输出,我在其中检查写入 profilePath 属性

的值

响应:

{"adult":false,"gender":2,"id":544002,"known_for_department":"Acting","name":"Giulio Berruti","original_name":"Giulio Berruti","popularity":2.467,"profile_path":"/ktPKniWGVkm6eBG7a2R7WGd96kZ.jpg","cast_id":1,"character":"Gabriel Emerson","credit_id":"5fdad9cfeda4b70041400df3","order":1},{"adult":false,"gender":0,"id":2897282,"known_for_department":"Acting","name":"Rhett Wellington","original_name":"Rhett Wellington","popularity":0.6,"profile_path":null,"cast_id":2,"character":"Simon Talbot","credit_id":"5fdad9dd3f7e1d004042f859","order":2}

控制台输出:

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
            print("JSON String: \(String(data: data!, encoding: .utf8))") //checking response
            let movies = try! JSONDecoder().decode(MovieCreditResponse.self, from: data!)
            
            for cast in movies.cast {
                print("Profile path - " + (cast.profilePath ?? "nil")) //checking profilePath property
            }
            
            DispatchQueue.main.async {
                completion(movies )
            }
        }
        .resume()
    }
struct MovieCreditResponse: Codable {
    let cast: [MovieCast]
}

struct MovieCast: Identifiable, Codable {
    let id: Int
    let character: String
    let name: String
    let profilePath: String?
}

JSON 文件中的 属性 名称是 profile_path,但您尝试将其解码为 profilePath。 您应该添加一个枚举来定义 JSON 键,例如

enum CodingKeys: String, CodingKey {
    case profilePath = "profile_path"
    // add the other keys as well
}

JSON 中 profilePath 属性 的密钥是 profile_path。因此,您只需将 JSONDecoderkeyDecodingStrategy 属性 设置为 .convertFromSnakeCase 即可正确解码:

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
    let movies = try JSONDecoder().decode(MovieCreditResponse.self, from: data!)
} catch {
    // Handle error
    print(error)
}

此外,通常使用 try! 是非常糟糕的做法。您应该 do-try-catch 并处理任何抛出的错误。