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

SwiftUI调用YouTube Data API获取播放列表视频失败求助

问题修复方案

1. 修复API请求URL的错误

你的urlString存在两处错误:API Key使用了无效的硬编码格式,且播放列表ID重复写死。修正为字符串插值写法,确保参数正确传递:

let urlString = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet,contentDetails,status&playlistId=\(playlistId)&key=\(apiKey)&maxResults=30"

2. 修正SearchResponse的Codable结构

YouTube API返回的字段存在可选性,当前的结构体强制要求必选字段会导致解码失败:

  • nextPageToken:没有下一页时不会返回,需设为可选
  • thumbnails中的standard/maxres:部分视频没有高分辨率缩略图,需设为可选

修正后的结构:

struct SearchResponse: Codable {
    let items: [Item]
    let nextPageToken: String? // 改为可选
    
    struct Item: Codable {
        let snippet: Snippet
        
        struct Snippet: Codable {
            let title: String
            let thumbnails: Thumbnail
            let resourceId: ResourceId
            
            struct Thumbnail: Codable {
                let standard: ThumbnailImage? // 改为可选
                let maxres: ThumbnailImage? // 改为可选
                
                struct ThumbnailImage: Codable {
                    let url: URL
                }
            }
            
            struct ResourceId: Codable {
                let videoId: String
            }
        }
    }
}

3. 处理可选缩略图URL

因为缩略图可能不存在,创建Video时需要做降级处理:

for item in searchResponse.items {
    // 优先取高分辨率缩略图,无则降级到standard,最后用默认图兜底
    let thumbnailUrl = item.snippet.thumbnails.maxres?.url 
        ?? item.snippet.thumbnails.standard?.url 
        ?? URL(string: "https://via.placeholder.com/130x70")!
    
    let newVideo = Video(title: item.snippet.title,
                         thumbnailUrl: thumbnailUrl,
                         videoId: item.snippet.resourceId.videoId)
    newVideos.append(newVideo)
}

4. 排查解码错误

在catch块中打印完整错误信息,确认解码是否失败:

catch {
    print("解码失败:\(error.localizedDescription)")
    print("错误详情:\(error)")
}

5. 修复ListView的图片加载问题

当前用Data(contentsOf:)在主线程同步加载图片会阻塞UI,改用iOS15+支持的AsyncImage异步加载:

HStack {
    AsyncImage(url: video.thumbnailUrl) { phase in
        switch phase {
        case .empty:
            Color.gray.frame(width: 130, height: 70)
        case .success(let image):
            image.resizable().frame(width: 130, height: 70)
        case .failure:
            Color.gray.frame(width: 130, height: 70)
        @unknown default:
            Color.gray.frame(width: 130, height: 70)
        }
    }
    Text(video.title).bold()
}

额外检查项

  • 确认你的API Key已启用YouTube Data API v3权限,且未超出调用配额
  • 可以在解码前打印原始返回数据,确认API响应正常:
    if let data = data {
        print("API返回数据:\(String(data: data, encoding: .utf8) ?? "无法解析")")
        // 后续解码逻辑
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:07:21