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

Alamofire请求出现responseSerializationFailed解码错误的技术问询

解决Alamofire POST请求解码错误:预期String但实际返回字典

问题背景

使用Alamofire调用接口https://new.demozab.com/armup/api/public/api/post-trade时,收到解码失败错误:

failure(Alamofire.AFError.responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.decodingFailed(error: Swift.DecodingError.typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "message", intValue: nil)], debugDescription: "Expected to decode String but found a dictionary instead.", underlyingError: nil)))))

请求代码

func postAd(cryptoo: String, fiatt: String,locationn: String,countryy: String,marginn: String,
            pricee: String,minlimitt: String,maxlimitt: String,paymrntwindoww: String,paymrntmethodd: String,
            accountdetailss: String,infoo: String,termss: String
){
                    
    let endpoint = "https://new.demozab.com/armup/api/public/api/post-trade"
    
    let params = [
        "crypto_currency_id":"1",
        "trade_type": "buy",
        "location": "",
        "country": "1",
        "market":"15",
        "margin":"1",
        "trade_price":"1",
        "min_transaction_limit":"1",
        "max_transaction_limit":"1",
        "payment_method":"1",
        "payment_window":"1",
        "account_details": "1",
        "additional_information":"1",
        "sunday_start":"",
        "sunday_end":"",
        "monday_start":"",
        "monday_end":"",
        "tuesday_start":"",
        "tuesday_end":"",
        "wednesday_start":"",
        "wednesday_end":"",
        "thursday_start":"",
        "thursday_end":"",
        "friday_start":"",
        "friday_end": "",
        "saturday_start": "",
        "saturday_end": "",
        "terms":"i",
    ]
     guard let url = URL(string: endpoint)
    else {
        print("Invalid URL")
        return
    }
    let headers: HTTPHeaders = [
        "Authorization": "Bearer TVfXc1gPZbLfruJ53Q7PkkSDjSXi6gXGWXkCXg6j",
        "Content-Type": "application/json"
    ]

    AF.request( url, method: .post, parameters: params,  headers: headers ).responseDecodable(of: CommonData.self) {
        (response) in
        print(response.result)
    }   
}

提供的API成功响应

{
    "success": true,
    "message": "Advertisement Posted Successfully!"
}

现有Model类

import Foundation

// MARK: - CommonData
struct CommonData: Codable {
    let success: Bool
    let message: String
}

问题原因

虽然你提供的成功响应中message是字符串,但错误提示明确表明:接口在某些异常场景(比如参数校验失败、权限问题等)下,返回的message字段是字典类型,而你的CommonData模型仅将message定义为String,导致JSON解码时类型不匹配。

解决方案

方案1:修改Model支持多类型的message

使用枚举来兼容String和Dictionary两种类型的message,确保所有场景都能正常解码:

import Foundation

// MARK: - CommonData
struct CommonData: Codable {
    let success: Bool
    let message: MessageType
}

enum MessageType: Codable {
    case string(String)
    case dictionary([String: Any])
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        // 先尝试解码为String
        if let stringValue = try? container.decode(String.self) {
            self = .string(stringValue)
        } 
        // 再尝试解码为字典
        else if let dictValue = try? container.decode([String: Any].self) {
            self = .dictionary(dictValue)
        } 
        // 都不符合则抛出错误
        else {
            throw DecodingError.typeMismatch(MessageType.self, DecodingError.Context(
                codingPath: decoder.codingPath, 
                debugDescription: "Expected String or Dictionary type for 'message'"
            ))
        }
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .string(let value):
            try container.encode(value)
        case .dictionary(let value):
            try container.encode(value)
        }
    }
}

方案2:手动解析JSON响应

如果不想修改Model,可以直接解析JSON对象,手动处理message字段:

AF.request(url, method: .post, parameters: params, headers: headers).responseJSON { response in
    switch response.result {
    case .success(let json):
        guard let responseDict = json as? [String: Any] else {
            print("Invalid response format")
            return
        }
        
        let success = responseDict["success"] as? Bool ?? false
        var messageContent = ""
        
        // 处理message字段的两种可能类型
        if let msgString = responseDict["message"] as? String {
            messageContent = msgString
        } else if let msgDict = responseDict["message"] as? [String: String] {
            // 取字典中的第一个值,或根据业务需求处理
            messageContent = msgDict.values.first ?? "Unknown error"
        }
        
        // 后续业务逻辑处理
        print("Success: \(success), Message: \(messageContent)")
        
    case .failure(let error):
        print("Request failed: \(error.localizedDescription)")
    }
}

额外排查建议

  • 用Postman或类似工具,传入相同请求参数,测试错误场景下的接口响应,确认message字段的实际结构
  • 检查请求参数是否符合接口要求,比如location为空、terms值为"i"是否符合规范,参数错误可能是导致接口返回异常格式响应的原因

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 12:55:03