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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:05:01