Flutter调用YouTube API获取分类时遇类型不匹配错误求助
问题分析与解决
错误根源
你遇到的type 'String' is not a subtype of type 'int' of 'index'错误,是因为错误遍历了整个API返回的Map对象(包含kind、etag、items等键)。当遍历到非items的键时,对应的value是字符串或其他非列表类型,此时尝试用value['items']访问,相当于给字符串使用字符串类型的索引——但字符串的索引只能是整数,因此触发类型错误。
分步修正
1. 修正异步请求代码
不需要遍历整个返回结果,直接提取items列表(这才是包含所有播放列表数据的数组),再将每个列表元素转换为YoutubeCategory对象:
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import '../models/youtube_category.dart'; class YoutubeProvider with ChangeNotifier { List<YoutubeCategory> _youtubeCategories = []; Future<void> categoryFetchAndSet() async { try { final url = Uri.parse( 'https://youtube.googleapis.com/youtube/v3/playlists?part=snippet&channelId=....'); final response = await http.get(url); final extractedData = json.decode(response.body) as Map<String, dynamic>; // 提取items列表 final List<dynamic> playlistItems = extractedData['items']; // 转换为YoutubeCategory列表 _youtubeCategories = playlistItems .map((item) => YoutubeCategory.fromJson(item as Map<String, dynamic>)) .toList(); notifyListeners(); // 通知UI更新数据 } catch (error) { print(error); rethrow; // 可将错误抛出给调用者处理 } } }
2. 修正模型代码
你的模型存在两处问题:
categoryId错误取了频道ID(snippet.channelId),应该取播放列表自身的ID(json['id'])- 直接访问
maxres缩略图可能因该分辨率不存在报错,需要做降级处理
修正后的模型:
class YoutubeCategory { String categoryId; String categoryName; String categoryPosterUrl; String categoryPostDate; YoutubeCategory({ required this.categoryId, required this.categoryName, required this.categoryPostDate, required this.categoryPosterUrl, }); factory YoutubeCategory.fromJson(Map<String, dynamic> json) { // 按优先级降级获取缩略图 final thumbnails = json['snippet']['thumbnails'] as Map<String, dynamic>; String posterUrl; if (thumbnails.containsKey('maxres')) { posterUrl = thumbnails['maxres']['url'] as String; } else if (thumbnails.containsKey('high')) { posterUrl = thumbnails['high']['url'] as String; } else if (thumbnails.containsKey('medium')) { posterUrl = thumbnails['medium']['url'] as String; } else { posterUrl = thumbnails['default']['url'] as String; } return YoutubeCategory( categoryId: json['id'] as String, categoryName: json['snippet']['title'] as String, categoryPostDate: json['snippet']['publishedAt'] as String, categoryPosterUrl: posterUrl, ); } }
额外注意事项
- 确保API请求URL中包含有效的
key参数(当前URL缺少),否则YouTube API会返回权限错误 - 若API返回字段可能为空,建议给模型字段添加
?标记为可选,并在转换时做空值判断 - 可使用
json_serializable包自动生成模型转换代码,减少手动编写的错误
内容的提问来源于stack exchange,提问作者Maenda
相关产品推荐
相关产品推荐

