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

5

我希望在收到请求数据后呈现一个视图,类似这样的:

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()
        }

    }
2个回答

10

将业务逻辑与 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 讲座: SwiftUI 中的数据流

它可以使上述所有内容清晰明了。


1
非常感谢。 - Sorin Lica

0

我认为你可以这样做:

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()
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接