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

iOS Swift使用Alamofire请求接口时__NSDictionaryI无法转Data报错问题

报错原因

你调用了Alamofire的responseJSON响应回调,这个方法会自动把接口返回的原始JSON Data解析成Foundation类型(字典、数组等,你本次返回的是不可变字典,对应报错里的__NSDictionaryI),所以response.result.value已经是解析后的字典对象,你强制转换成Data类型自然会触发类型转换失败的崩溃。

解决方案

提供两种可选修复方式,优先推荐方案1:

方案1:改用responseData回调拿原始数据解码

将原来的.responseJSON回调改为.responseData,直接拿到接口返回的原始二进制数据传给JSONDecoder解码即可,修改后的完整代码如下:

class func callPostServiceReturnJson(apiUrl urlString: String, parameters params : [String: AnyObject]?,  parentViewController parentVC: UIViewController, successBlock success : @escaping ( _ responseData : AnyObject, _  message: String) -> Void, failureBlock failure: @escaping (_ error: Error) -> Void) {
        
        if Utility.checkNetworkConnectivityWithDisplayAlert(isShowAlert: true) {
            // 下方手动拼接参数的代码没有实际使用,可以直接删除
            var strMainUrl:String! = urlString + "?"
            for dicd in params! {
                strMainUrl.append("\(dicd.key)=\(dicd.value)&")
            }
            print("Print Rest API : \(strMainUrl ?? "")")

            let manager = Alamofire.SessionManager.default
            manager.session.configuration.timeoutIntervalForRequest = 120
            // 此处将responseJSON改为responseData
            manager.request(urlString, method: .get, parameters: params)
                .responseData { response in
                    switch (response.result) {
                    case .success(let data):
                        do{
                            let users = try JSONDecoder().decode(OrderStore.self, from: data)
                            // 解码成功后可按需将users对象传入success回调
                        }catch{
                            print("数据解码错误: \(error)")
                        }
                        if let value = response.result.value {
                            success(value as AnyObject, "操作成功")
                        }
                        break
                    case .failure(let error):
                        print(error)
                        if error._code == NSURLErrorTimedOut {
                            print(error.localizedDescription)
                            failure(error)
                        } else {
                            print("\n\n认证请求失败,错误信息:\n \(error)")
                            failure(error)
                        }
                        break
                    }
            }
        } else {
            parentVC.hideProgressBar();
            Utility.showAlertMessage(withTitle: EMPTY_STRING, message: NETWORK_ERROR_MSG, delegate: nil, parentViewController: parentVC)
        }
    }

方案2:将已解析的字典转成Data再解码

如果你需要保留responseJSON回调的逻辑,可以先把拿到的字典通过JSONSerialization序列化为Data,再传给JSONDecoder解码,这种方式多了一次序列化操作,性能略低于方案1:

do {
    guard let jsonDic = response.result.value as? [String: Any] else {
        // 处理返回值不是字典的异常
        return
    }
    let data = try JSONSerialization.data(withJSONObject: jsonDic)
    let users = try JSONDecoder().decode(OrderStore.self, from: data)
} catch {
    print("数据解码错误: \(error)")
}

额外优化提示:你代码中手动拼接GET参数生成的strMainUrl没有被实际传入请求使用,Alamofire的request方法传入parameters参数后会自动拼接GET请求的查询参数,这段冗余的拼接代码可以直接删除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 06:09:04