使用SwiftyJSON与Alamofire遇索引越界,如何跳过无结果项?
解决YouTube API请求无结果时的数组越界问题
嘿,这个问题我太熟了!你之所以触发fatal error: Index out of range,核心原因就是当没有匹配视频时,YouTube返回的items数组是空的,但你直接去访问了items[0]这个索引——空数组根本没有第0个元素,自然就崩溃了。
要跳过无结果项继续执行,关键就是在提取数据前先做安全检查,确保结果存在再处理。下面给你一步步讲怎么改:
核心思路
- 解析JSON时,先安全获取返回的
items数组 - 判断数组是否为空:空的话直接跳过当前请求,继续处理下一个文件名
- 非空时再去提取
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
相关产品推荐
相关产品推荐

