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

使用SwiftyJSON与Alamofire遇索引越界,如何跳过无结果项?

解决YouTube API请求无结果时的数组越界问题

嘿,这个问题我太熟了!你之所以触发fatal error: Index out of range,核心原因就是当没有匹配视频时,YouTube返回的items数组是空的,但你直接去访问了items[0]这个索引——空数组根本没有第0个元素,自然就崩溃了。

要跳过无结果项继续执行,关键就是在提取数据前先做安全检查,确保结果存在再处理。下面给你一步步讲怎么改:

核心思路

  1. 解析JSON时,先安全获取返回的items数组
  2. 判断数组是否为空:空的话直接跳过当前请求,继续处理下一个文件名
  3. 非空时再去提取videoId,同时用可选绑定避免强制解包带来的崩溃

具体代码示例

假设你原本的请求逻辑是遍历文件名列表发起请求,改成这样就没问题了:

// 假设你有个存储videoId的数组
var videoIds: [String] = []
// 遍历你的文件名列表
for filename in yourFilenameList {
    // 构造YouTube搜索参数(记得替换成你的API Key)
    let params: Parameters = [
        "q": filename,
        "key": "YOUR_YOUTUBE_API_KEY",
        "part": "id",
        "type": "video"
    ]
    
    Alamofire.request("https://www.googleapis.com/youtube/v3/search", parameters: params).responseJSON { response in
        // 先安全解析JSON和items数组
        guard let json = response.result.value as? [String: Any],
              let items = json["items"] as? [[String: Any]],
              !items.isEmpty else {
            // 没有匹配结果,打印提示然后跳过
            print("⚠️ 没有找到匹配视频:\(filename)")
            return
        }
        
        // 安全提取videoId
        if let idDict = items[0]["id"] as? [String: Any],
           let videoId = idDict["videoId"] as? String {
            // 这里记得如果是更新UI相关的数组,要切回主线程
            DispatchQueue.main.async {
                self.videoIds.append(videoId)
                print("✅ 成功添加videoId:\(videoId)(对应文件名:\(filename))")
            }
        } else {
            // 偶尔会遇到返回结构不符合预期的情况,也跳过
            print("⚠️ 响应结构异常,跳过:\(filename)")
        }
    }
}

额外注意事项

  • 绝对避免强制解包:别用!去强制转换类型或者取数组元素,用if let/guard let做可选绑定才是安全的
  • 异步请求的线程安全:如果videoIds是用来更新UI的,一定要用DispatchQueue.main.async回到主线程操作,不然会触发UI线程异常
  • 批量请求的管理:如果文件名很多,建议用DispatchGroup来跟踪所有请求的完成状态,方便后续做统一处理(比如所有请求完成后通知用户)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:24:00