简体   繁体   English

如何在 swiftui 中显示来自自定义 class 的警报?

[英]How do I present an alert from a custom class in swiftui?

In SwiftUI, I have a network request running in scenedelegate, scenedidbecomeactive.在 SwiftUI 中,我在 scenedelegate 中运行了一个网络请求,scenedid 变得活跃。 I don't know which view the user will be on when the app becomes active, but I want to present an alert if the data in the network request changes.我不知道当应用程序处于活动状态时用户将使用哪个视图,但我想在网络请求中的数据发生变化时发出警报。 I simplified the code below, so it's easy to read...我简化了下面的代码,所以很容易阅读......

 func sceneDidBecomeActive(_ scene: UIScene) {
            let customClass = CustomClass()
            customClass.performNetworkRequest()

In CustomClass, i have...在 CustomClass 中,我有...

func performNetWorkRequest() {
URLSession.shared.dataTask(with: url) { (data, response, error) in          
      if let d = data {
         let response = try JSONDecoder().decode(DetailResponse.self, from: d)
             DispatchQueue.main.async {
                 //Here is where I want to either present an alert, but I can't figure out how to.
                 //OR do i put a func in SceneDeletegate to present the alert on the window.rootviewcontroller and then just call that func from here?
}

Any help is much appreciated!任何帮助深表感谢!

Paul has a point - here's a possible implementation:保罗有一点 - 这是一个可能的实现:

// In CustomClass.swift

import Combine

class CustomClass : ObservableObject {

    @Published var dataRecieved = PassthroughSubject<DetailResponse, Never>()

    init() {
        performNetWorkRequest()
    }

    func performNetWorkRequest() {
        URLSession.shared.dataTask(with: url) { (data, response, error) in

            let response = try JSONDecoder().decode(DetailResponse.self, from: data)

            DispatchQueue.main.async {
                self.dataRecieved.send(response)
            }
        }
        .resume()
    }
}

// In SomeView.swift

import SwiftUI
import Combine

struct ContentView: View {

    @State var showAlert = false
    var customClass = CustomClass()

    var body: some View {
        Text("Hello, World!")
            .onReceive(customClass.dataRecieved) { _ in
                self.showAlert = true
            }
            .alert(isPresented: $showAlert) {
            // your alert
            }
    }
}

Notice I didn't mention the SceneDelegate in any of these - this approach (called MVVM ) is more flexible, in my opinion - besides, the way it is set up, performNetWorkRequest() will be executed as soon as your view is initialized, anyway.请注意,我没有在其中任何一个中提到 SceneDelegate - 在我看来,这种方法(称为MVVM )更灵活 - 此外,它的设置方式, performNetWorkRequest()将在您的视图初始化后立即执行,反正。 You can also tweak the PassthroughSubject - I didn't know if you needed the DetailResponse or not.您还可以调整PassthroughSubject - 我不知道您是否需要DetailResponse Hope this helped!希望这有帮助!

Edit:编辑:

I just reread your question and it seems that this implementation is at fault as you noted there was no way to know what view the user would be on in the case of a network change.我刚刚重新阅读了您的问题,并且您指出无法知道在网络更改的情况下用户将使用什么视图,因此该实现似乎有问题。 In that case, you can feed the same instance of CustomClass in your SceneDelegate as an EnvironmentObject .在这种情况下,您可以在SceneDelegate中将相同的CustomClass实例作为EnvironmentObject提供。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM