Swift中如何在View中展示completion handler返回的异步值
解决方案
你需要按照SwiftUI响应式数据流规范改造代码,核心思路是让数据层的变更可以主动通知视图刷新,具体操作如下:
第一步:改造Commands类
让它遵循ObservableObject协议,把需要通知视图更新的属性用@Published修饰:
import Alamofire import SwiftUI class Commands: ObservableObject { // @Published修饰的属性变更时,会自动给视图发送更新通知 @Published var status_code: String = "0" private let credentials: Credentials // 替换为你实际的Credentials类型 init(credentials: Credentials) { self.credentials = credentials } private func send(method: String, path: String, code: Array<Int>, headers: HTTPHeaders, completionHandler: @escaping (Int) -> Void) { let url: String = "\(self.credentials.url)/\(path)" AF.request(url, method: HTTPMethod(rawValue: method), headers: headers) .authenticate(with: self.request_credentials) .response { response in // 替换强制解包为可选绑定,避免网络异常时闪退 guard let statusCode = response.response?.statusCode else { // 可自定义异常场景的返回码 completionHandler(-1) return } completionHandler(statusCode) } } func list_files(path: String) { let headers: HTTPHeaders = [ "Depth": "1" ] // 加[weak self]避免循环引用 send(method: "PROPFIND", path: path, code: [207, 301], headers: headers) { [weak self] status_code in // 显式指定主线程更新属性,保证UI刷新逻辑安全 DispatchQueue.main.async { self?.status_code = String(status_code) } } } }
第二步:改造ContentView视图
使用@StateObject持有ObservableObject实例,把网络请求放到onAppear生命周期回调中执行,不要在body的计算过程中初始化实例和发起请求:
struct ContentView: View { // @StateObject保证实例在视图生命周期内唯一,不会因为视图重绘被销毁重建 @StateObject private var commands: Commands init() { let auth = Authentication( username: "****", domain: "****", password: "****", port: ****, proto: "****", path:"****" ) // @StateObject的标准初始化方式 _commands = StateObject(wrappedValue: Commands(credentials: auth.get_credentials())) } var body: some View { Text(commands.status_code) .padding() .onAppear { // 视图渲染完成后发起异步请求 commands.list_files(path: "/") } } }
内容的提问来源于stack exchange,提问作者AdamSwift
相关产品推荐
相关产品推荐

