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

Swift异步请求completion参数缺失报错及Response返回方案咨询

问题原因
  • 你定义的createList方法明确要求传入completion闭包参数,调用时省略该参数自然会触发参数缺失报错
  • 给闭包设置默认值nil报错是因为没有将闭包类型声明为可选,只有可选类型才支持赋值为nil
  • 异步请求不可能直接同步返回结果,你想要的if barback.createList(...).status == 200这种同步写法逻辑上不成立,必须通过回调或者异步语法处理返回结果
  • 原函数还存在隐藏bug:请求失败时仅打印错误,没有调用completion回传结果,会导致上层始终收不到失败回调
修复方案

方案1:基于闭包回调实现(兼容所有iOS版本)

第一步:优化函数定义

// 把闭包参数声明为可选,设置默认空实现,支持不传completion的调用场景
// 入参改为Result类型,同时支持回传成功和失败结果
func createList(name: String, completion: @escaping (Result<Response, Error>) -> Void = { _ in }) {
    // 避免强制解包崩溃,先校验用户登录状态
    guard let uid = session.auth.currentUser?.uid else {
        completion(.failure(NSError(domain: "AppError", code: -1, userInfo: [NSLocalizedDescriptionKey: "用户未登录"])))
        return
    }
    let parameters = ["name": name, "user_id": uid]
    
    AF.request("\(url)/wishlist", method: .post, parameters: parameters, encoding: URLEncoding.default).responseDecodable(of: Response.self) { response in
        switch response.result {
        case .failure(let err):
            print(err)
            completion(.failure(err))
        case .success(let res):
            completion(.success(res))
        }
    }
}

第二步:按钮点击处调用

barback.createList(name: name) { result in
    // 切回主线程操作UI,避免子线程操作UI导致的崩溃
    DispatchQueue.main.async {
        switch result {
        case .success(let response):
            if response.status == 200 {
                // 触发对应的UI逻辑
            } else {
                // 展示业务错误toast
            }
        case .failure(_):
            // 展示请求失败toast
        }
    }
}

方案2:基于async/await实现(iOS 15+/Swift 5.5+支持,写法更简洁)

第一步:定义异步函数

func createList(name: String) async throws -> Response {
    guard let uid = session.auth.currentUser?.uid else {
        throw NSError(domain: "AppError", code: -1, userInfo: [NSLocalizedDescriptionKey: "用户未登录"])
    }
    let parameters = ["name": name, "user_id": uid]
    // 调用Alamofire内置的异步方法
    return try await AF.request("\(url)/wishlist", method: .post, parameters: parameters, encoding: URLEncoding.default)
        .serializingDecodable(Response.self)
        .value
}

第二步:按钮点击处调用

Task {
    do {
        let response = try await barback.createList(name: name)
        await MainActor.run {
            if response.status == 200 {
                // 触发对应的UI逻辑
            } else {
                // 展示业务错误toast
            }
        }
    } catch {
        await MainActor.run {
            // 展示请求失败toast
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 10:51:01