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

iOS开发:网络下载数据存设备内部失败,类型转换报错求助

解决Cannot convert value of type 'ServerConnect.Result' to expected argument type 'Data'问题

这个错误的核心原因很直白:你在getJsonProducts的completion回调里拿到的参数data并不是直接的Data类型,而是你自定义的ServerConnect.Result<Data>枚举类型。你得先解析这个枚举,取出成功状态下的真实Data,再传给保存函数。

具体修改步骤:

  • 在completion回调中,通过switch或者if case判断Result的状态:
    • 匹配到.success(data)时,把这个data传给保存函数
    • 匹配到.error(message)时,添加错误日志或用户提示逻辑

修改后的完整代码示例:

首先先修正ServerConnect里的小细节(比如拼写错误、强制解包风险):

struct ServerConnect {
    enum Result<T> {
        case success(T) // 修正拼写错误:succes → success
        case error(String)
    }
    
    typealias CompletionHandler = (Result<Data>) -> () // 遵循Swift命名规范,首字母大写
    
    func getJsonFromServer(parameters: String, completion: @escaping CompletionHandler) {
        let fullUrlString = ApiConstans.fullPath + parameters
        guard let url = URL(string: fullUrlString) else {
            let errorMsg = ErrorsLabels.ServerConnect01
            debugPrint(errorMsg)
            return completion(.error(errorMsg))
        }
        
        URLSession.shared.dataTask(with: url) { (data, response, error) in
            if let error = error {
                let errorMsg = ErrorsLabels.ServerConnect02
                debugPrint("\(errorMsg): \(error.localizedDescription)")
                return completion(.error(errorMsg))
            }
            
            guard let data = data else {
                let errorMsg = ErrorsLabels.ServerConnect03
                debugPrint(errorMsg)
                return completion(.error(errorMsg))
            }
            
            debugPrint("R> \(fullUrlString)")
            completion(.success(data))
        }.resume()
    }
    
    func getJsonProducts(lang: String?, region: Int?, completion: @escaping CompletionHandler) {
        // 用可选绑定替代强制解包,避免nil崩溃
        guard let lang = lang, let region = region else {
            debugPrint("Lang or region parameter is nil")
            return completion(.error("Invalid language or region"))
        }
        let parameters = "?action=GET_PRODUCTS&lang=\(lang)&region=\(region)"
        self.getJsonFromServer(parameters: parameters, completion: completion)
    }
}

然后修改调用getJsonProducts的代码,正确处理Result枚举:

getJsonProducts(lang: selectedLanguage, region: selectedRegion) { result in
    switch result {
    case .success(let data):
        print("@@@@@ Successfully fetched data")
        saveJsonFileToTheDisk(path: "\(selectedLanguage)/json/products.json", downloadData: data)
    case .error(let message):
        print("Failed to fetch data: \(message)")
        // 这里可以添加用户提示,比如弹出Alert告知加载失败
    }
}

func saveJsonFileToTheDisk(path: String, downloadData: Data){
    do {
        let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        // 先创建目标目录,避免路径不存在导致写入失败
        let directoryURL = documentsURL.appendingPathComponent("\(selectedLanguage)/json")
        try FileManager.default.createDirectory(at: directoryURL, withIntermediateDirectories: true)
        
        let fileURL = documentsURL.appendingPathComponent(path)
        try downloadData.write(to: fileURL, options: .atomic)
        print("File saved successfully at: \(fileURL.path)")
    } catch {
        print("Failed to save file: \(error.localizedDescription)")
    }
}

额外优化说明:

  1. 修正了Result枚举的拼写错误,避免后续调用时出现不必要的bug
  2. 替换强制解包为可选绑定,降低崩溃风险
  3. 在保存函数中添加了目录创建逻辑,确保保存路径的目录存在
  4. 补充了错误分支的日志输出,方便调试排查问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:22:28