如何在 SwiftUI 中使用 URLSession 请求后呈现视图?

How to present a view after a request with URLSession in SwiftUI?

我想在收到请求的数据后呈现一个视图,像这样

var body: some View {
          VStack {
            Text("Company ID")
            TextField($companyID).textFieldStyle(.roundedBorder)

            URLSession.shared.dataTask(with: url) { (data, _, _) in
                guard let data = data else { return }

                DispatchQueue.main.async {
                    self.presentation(Modal(LogonView(), onDismiss: {
                        print("dismiss")
                    }))
                }
            }.resume()
        }

    }

我认为你可以这样做:

var body: some View {
        VStack {
            Text("Company ID")
        }
        .onAppear() {
            self.loadContent()
        }
    }

    private func loadContent() {
        let url = URL(string: "https://your.url")!
        URLSession.shared.dataTask(with: url) { (data, _, _) in
            guard let data = data else { return }
            DispatchQueue.main.async {
                self.presentation(Modal(ContentView(), onDismiss: {
                    print("dismiss")
                }))
            }
            }.resume()
    }

业务逻辑与 UI 代码混合在一起会带来麻烦。

您可以按如下方式创建模型对象 @ObjectBinding

class Model: BindableObject {

    var didChange = PassthroughSubject<Void, Never>()

    var shouldPresentModal = false {
        didSet {
            didChange.send(())
        }
    }

    func fetch() {
        // Request goes here
        // Edit `shouldPresentModel` accordingly
    }
}

视图可能类似于...

struct ContentView : View {

    @ObjectBinding var model: Model

    @State var companyID: String = ""

    var body: some View {
        VStack {
            Text("Company ID")
            TextField($companyID).textFieldStyle(.roundedBorder)
            if (model.shouldPresentModal) {
                // presentation logic goes here
            }
        }.onAppear {
            self.model.fetch()
        }
    }
}

它的工作方式:

  • VStack出现时,模型fetch函数被调用并执行
  • 当请求成功时 shouldPresentModal 设置为 true,并向下发送消息 PassthroughSubject
  • 作为该主题订阅者的视图知道模型已更改并触发重绘。
  • 如果 shouldPresentModal 设置为 true,将执行额外的 UI 绘图。

我推荐观看这个精彩的 WWDC 2019 演讲: Data Flow Through Swift UI

上面的一切都清楚了。