Swift如何将URLSession HTTP请求的response暴露给其他函数
核心原因
你加public不生效的根本原因有两个:
public是用于修饰类/结构体/枚举的属性、方法、类型本身访问权限的关键字,不能用来修饰函数、闭包内部的局部变量- 你声明的
response是dataTask异步回调闭包里的局部变量,作用域仅限这个闭包内部,外部无法直接访问,和访问权限无关
方案1:使用自定义完成回调传值(适配所有Swift版本)
给发起网络请求的函数加一个逃逸闭包参数,请求完成后把结果通过这个闭包传到外部:
// 定义请求函数,加完成回调参数 func requestAPI(completion: @escaping (String?) -> Void) { let url = URL(string: APILink)! let task = URLSession.shared.dataTask(with: url) {(data, response, error) in guard let data = data, let responseStr = String(data: data, encoding: .utf8) else { completion(nil) return } completion(responseStr) } task.resume() } // 调用示例,在回调里拿到结果传给其他函数 requestAPI { response in guard let response = response else { return } // 在这里可以把response传给任意其他函数使用 yourOtherFunction(response: response) // 如果需要更新UI,记得切到主线程 DispatchQueue.main.async { // 执行UI更新操作 } }
方案2:使用async/await(Swift 5.5+支持,代码更简洁)
如果你的项目最低支持iOS 15+/macOS 12+,可以用现代异步写法避免回调嵌套:
func requestAPI() async throws -> String { let url = URL(string: APILink)! let (data, _) = try await URLSession.shared.data(from: url) guard let responseStr = String(data: data, encoding: .utf8) else { throw NSError(domain: "ParseError", code: -1) } return responseStr } // 调用示例 Task { do { let response = try await requestAPI() // 直接拿到response传给其他函数 yourOtherFunction(response: response) } catch { // 处理错误逻辑 print(error) } }
方案3:存储为实例属性(需要长期留存结果时使用)
如果你需要后续多处随时访问这个结果,可以把它存为当前类/结构体的属性:
class YourDataManager { // 声明实例属性存储返回结果 var apiResponse: String? func requestAPI() { let url = URL(string: APILink)! let task = URLSession.shared.dataTask(with: url) {[weak self] (data, response, error) in guard let self = self, let data = data, let responseStr = String(data: data, encoding: .utf8) else { return } // 赋值给实例属性 self.apiResponse = responseStr // 赋值完成后可以在这里调用其他方法使用这个值 self.handleResponse() } task.resume() } func handleResponse() { guard let response = apiResponse else { return } // 在这里使用response print(response) } }
内容的提问来源于stack exchange,提问作者user16290104
相关产品推荐
相关产品推荐

