You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift开发:无法解码API链接并从数组获取电影标题的问题

问题分析与解决方案

核心问题

  1. 解码逻辑错误:你试图直接将API返回的完整JSON解码成单个字符串(title1本质是字符串"title"),但API返回的是包含page、results数组等字段的完整Movies结构,这种解码方式必然失败,导致输出"FAIL"。
  2. 类型认知偏差:[Result]是Result对象的数组,数组本身没有title属性,必须遍历数组中的每个Result实例才能获取对应的电影标题。

修正步骤与代码

1. 定义目标结构体(按需存储电影标题)

如果你只需要存储电影标题,可以定义一个极简结构体:

struct MovieTitle: Codable {
    let title: String
}

2. 修正API管理器的解码逻辑

重写APIManager的方法,先解码完整的Movies结构,再从results数组中提取标题并转换为目标结构体:

class APIManager {
    static let shared = APIManager()
    let urlString = "https://api.themoviedb.org/3/movie/popular?api_key=d35da28c5f884f89607c3388f07c2f5e"
    
    func getMovieTitles(completion: @escaping ([MovieTitle]) -> Void) {
        // 避免强制解包URL,防止崩溃
        guard let url = URL(string: urlString) else {
            print("无效的API地址")
            completion([])
            return
        }
        
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            // 处理请求错误
            if let error = error {
                print("请求失败: \(error.localizedDescription)")
                completion([])
                return
            }
            
            guard let data = data else {
                print("未获取到返回数据")
                completion([])
                return
            }
            
            do {
                // 先解码完整的Movies结构
                let movies = try JSONDecoder().decode(Movies.self, from: data)
                // 遍历results数组,提取每个电影的title并转换为目标结构体
                let movieTitles = movies.results.map { MovieTitle(title: $0.title) }
                // 切回主线程回调结果
                DispatchQueue.main.async {
                    completion(movieTitles)
                }
            } catch {
                // 打印解码错误详情,方便排查
                print("解码失败: \(error.localizedDescription)")
                completion([])
            }
        }
        task.resume()
    }
}

3. 优化结构体命名(避免冲突)

Result是Swift标准库的内置类型,建议将原Result结构体重命名为Movie,避免命名冲突:

struct Movies: Codable {
    let page: Int
    var results: [Movie]
    let totalPages, totalResults: Int
    
    enum CodingKeys: String, CodingKey {
        case page, results
        case totalPages = "total_pages"
        case totalResults = "total_results"
    }
}

struct Movie: Codable {
    let adult: Bool
    let backdropPath: String
    let genreIDS: [Int]
    let id: Int
    let originalLanguage: OriginalLanguage
    let originalTitle, overview: String
    let popularity: Double
    let posterPath, releaseDate, title: String
    let video: Bool
    let voteAverage: Double
    let voteCount: Int
    
    enum CodingKeys: String, CodingKey {
        case adult
        case backdropPath = "backdrop_path"
        case genreIDS = "genre_ids"
        case id
        case originalLanguage = "original_language"
        case originalTitle = "original_title"
        case overview, popularity
        case posterPath = "poster_path"
        case releaseDate = "release_date"
        case title, video
        case voteAverage = "vote_average"
        case voteCount = "vote_count"
    }
}

enum OriginalLanguage: String, Codable {
    case en = "en"
    case es = "es"
    case it = "it"
}

4. 使用示例

调用修正后的方法获取电影标题数组:

APIManager.shared.getMovieTitles { movieTitles in
    // 遍历打印所有标题
    for movieTitle in movieTitles {
        print(movieTitle.title)
    }
    // 此处可将movieTitles存入你需要的存储位置
}

内容的提问来源于stack exchange,提问作者DanTheMan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:23:21