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

时间:2019-06-10 13:56:44

标签: ios swift swiftui

从请求中接收数据后,我想呈现一个视图

namespace Xaminals.Views
{
    [QueryProperty("Name", "name")]
    public partial class CatDetailPage : ContentPage
    {
        public string Name
        {
            set
            {
                BindingContext = CatData.Cats.FirstOrDefault(m => m.Name == Uri.UnescapeDataString(value));
            }
        }

        public CatDetailPage()
        {
            InitializeComponent();
        }

        protected override bool OnBackButtonPressed()
        {
            return base.OnBackButtonPressed();
        }
    }
}

2 个答案:

答案 0 :(得分:6)

将业务逻辑与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

以上所有内容都很清楚。

答案 1 :(得分: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()
    }