类型不匹配。预期解码 Dictionary<String, Any> 但找到了一个数组

Posted

技术标签:

【中文标题】类型不匹配。预期解码 Dictionary<String, Any> 但找到了一个数组【英文标题】:typeMismatch. Expected to decode Dictionary<String, Any> but found an array instead 【发布时间】:2021-11-03 01:30:35 【问题描述】:

我找不到这个问题的答案。我正在尝试解析包含元素数组的 JSON 响应。这就是我从端点获取数据的方法:

func getCarruseles(completion: @escaping (Result<[CarruselesData], Error>)-> Void) 
        
        let urlString =  baseUrl + "url"
        
        guard let url = URL(string: urlString) else 
            completion(.failure(NetworkingError.badUrl))
            return
        
        
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        request.setValue("Bearer token", forHTTPHeaderField: "Authorization")
        
        let session = URLSession.shared

        let task = session.dataTask(with: request)  (data, response, error) in
            DispatchQueue.main.async 

                if let unwrappedError = error 
                    completion(.failure(unwrappedError))
                    return
                

                if let unwrappedData = data 
                    do
                        let json = try JSONSerialization.jsonObject(with: unwrappedData, options: [])
                        if let successRes = try? JSONDecoder().decode([CarruselesData].self, from: unwrappedData)
                            completion(.success(successRes))
                        else

                            let errorResponse = try JSONDecoder().decode(CarruselesErrorResponse.self, from: unwrappedData)
                            print("Error \(errorResponse)")
                            completion(.failure(errorResponse))
                        
                    catch
                        completion(.failure(error))
                    
                
            
        
        task.resume()
    

这是我用来解析数据的结构:

struct CarruselesData: Codable 
    let title: String
    let type: String
    let items: [Carrusel]


struct Carrusel: Codable 
    let title: String
    let imageUrl: String
    let videoUrl: String
    let description: String

这是我得到的回应:

(
        
        items =         (
                        
                description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
                imageUrl = "http://placeimg.com/640/480/any";
                title = "Movie 1";
                videoUrl = "https://d11gqohmu80ljn.cloudfront.net/128/media-20210712191955-cbdi-0.m3u8/master.m3u8";
            ,
                        
                description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
                imageUrl = "http://placeimg.com/640/480/any";
                title = "Movie 2";
                videoUrl = "https://d11gqohmu80ljn.cloudfront.net/128/media-20210712191955-cbdi-0.m3u8/master.m3u8";
            ,
                        
                description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
                imageUrl = "http://placeimg.com/640/480/any";
                title = "Movie 3";
            ,
                        
                description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
                imageUrl = "http://placeimg.com/640/480/any";
                title = "Movie 4";
                videoUrl = "https://d11gqohmu80ljn.cloudfront.net/128/media-20210712191955-cbdi-0.m3u8/master.m3u8";
            
        );
        title = "Carousel Thumb";
        type = thumb;
    ,
        
        items =         (
                        
                description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
                imageUrl = "http://placeimg.com/320/480/any";
                title = "Movie 1";
                videoUrl = "https://d11gqohmu80ljn.cloudfront.net/128/media-20210712191955-cbdi-0.m3u8/master.m3u8";
            ,
                        
                description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
                imageUrl = "http://placeimg.com/320/480/any";
                title = "Movie 2";
            
        );
        title = "Carousel Poster";
        type = poster;
    
)

这是我得到的错误: typeMismatch(Swift.Dictionary, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary but found an array而是。”,基础错误:无))

【问题讨论】:

【参考方案1】:

问题在于,在 items 数组中,并非所有项目都包含“videoURL”。为了解决这个问题,我只需要将 Carrusel 结构的 videoUrl 参数设置为 Optional,如下所示:

struct Carrusel: Codable 
    let title: String
    let imageUrl: String
    let videoUrl: String?
    let description: String

【讨论】:

以上是关于类型不匹配。预期解码 Dictionary<String, Any> 但找到了一个数组的主要内容,如果未能解决你的问题,请参考以下文章

JSONDecoder - “预期解码 Dictionary<String, Any> 但找到了一个字符串/数据。”

Swift JSON解码器类型不匹配错误

无法转换类型“字典<String, Any>?”的值?到预期的参数类型“数据”

尝试保存数组,出现错误 - 无法将类型“[Data]”的值转换为预期的参数类型“[Dictionary<String, AnyObject>]”

Swift Init 不符合预期的“解码器”类型

解码错误:“应解码 Dictionary<String, Any>,但找到了一个数组。”