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

Swift 4调用REST API未处理抛出错误求助(含SwiftyJSON代码)

解决NSMutableURLRequest调用REST API时的“Call can throw”错误

看起来你遇到的问题是Swift中抛出方法未被正确处理导致的编译错误。这个提示说明你调用了一个标记为throws的方法,但既没有用try关键字包裹,也没有处理可能抛出的错误。结合你的代码场景,最可能的问题出在SwiftyJSON解析JSON数据的步骤(毕竟你没写完的request.httpBody相关操作里,data(using:)方法本身不抛出错误)。

下面是修正后的完整代码,我会标注关键的修改点:

func getUserLogin(username: String, password: String, onSuccess: @escaping (JSON) -> Void, onFailure: @escaping (Error) -> Void) {
    // 1. 安全处理URL,避免强制解包崩溃
    let urlString = baseURL + APIManager.getUserLogin
    guard let url = URL(string: urlString) else {
        let invalidURLError = NSError(domain: "APIError", code: -1, userInfo: [
            NSLocalizedDescriptionKey: "无法构造有效的请求URL"
        ])
        onFailure(invalidURLError)
        return
    }
    
    let request = NSMutableURLRequest(url: url)
    request.httpMethod = "POST"
    
    // 2. 构造POST表单数据,设置请求体
    let postString = "username=\(username)&password=\(password)"
    request.httpBody = postString.data(using: .utf8)
    // 别忘了添加Content-Type头,服务器需要这个来解析表单数据
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    
    // 3. 发起网络请求并处理响应
    let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
        // 先处理网络层错误
        if let networkError = error {
            onFailure(networkError)
            return
        }
        
        // 确保收到数据
        guard let responseData = data else {
            let noDataError = NSError(domain: "APIError", code: -2, userInfo: [
                NSLocalizedDescriptionKey: "服务器未返回任何数据"
            ])
            onFailure(noDataError)
            return
        }
        
        // 4. 关键:用do-catch处理SwiftyJSON的抛出方法
        do {
            // JSON(data:)初始化器会抛出错误(比如数据不是有效JSON),必须用try包裹
            let json = try JSON(data: responseData)
            onSuccess(json)
        } catch let jsonParseError {
            // 捕获解析错误并传递给失败回调
            onFailure(jsonParseError)
        }
    }
    
    task.resume()
}

关键修改说明:

  • 移除强制解包:原代码中NSURL(string: url)!的强制解包很容易导致崩溃,换成guard let安全处理无效URL的情况,并通过onFailure传递错误。
  • 添加Content-Type头:POST表单数据时,必须告诉服务器请求体的格式,否则服务器可能无法正确解析你的用户名和密码参数。
  • 处理JSON解析的抛出错误:SwiftyJSON的JSON(data:)方法会在数据无效时抛出错误,所以必须用do-catch块包裹,把解析错误传递给调用者。
  • 完善错误传递:把所有可能的错误场景(无效URL、网络错误、无数据、解析错误)都通过onFailure回调暴露出去,方便上层处理。

如果你的错误是出在其他抛出方法上(比如自定义的参数编码方法),只需要找到那个方法,用try包裹并在do-catch中处理错误即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:23:13