带NotificationCenter发布者的SwiftUI

时间:2020-01-01 12:26:07

标签: swiftui combine notificationcenter

我想在应用程序进入后台并返回时收听通知。我正在尝试使用NotificationCenter发布者,并让SwiftUI视图收听它们。
我可以使用几种方法来执行此操作,而我尝试使用其中的两种方法,但有趣的是,尽管当我将订户放入init()方法中时,所有方法似乎都是合法的,但它根本无法工作。
我试图将其放在main线程上,但仍然没有成功。
有谁知道为什么吗?
这是我的代码:

struct ContentView: View {
    @State var isActive = true
    @State var cancellables = Set<AnyCancellable>()
    var body: some View {
        ZStack {
            Image("background")
                .resizable()
                .scaledToFill()
                .edgesIgnoringSafeArea(.all)                        
        }
        .onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
            self.isActive = false
        }
        .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification), perform: {_ in
            self.isActive = true
        })
    }

    init() {
        NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)
         //   .receive(on: RunLoop.main)
            .sink(receiveValue: { _ in
                print("init")
            }
            .store(in: &cancellables)
    }
}

奇怪的是,onReceive修饰符中的侦听器就像一个超级按钮。在init()中,print("init")永远不会被调用。

2 个答案:

答案 0 :(得分:3)

@State尚未在初始化中准备就绪,因此无法用于此类目的。该方法可以如下:

var cancellables = Set<AnyCancellable>()
init() {
    NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)
        .sink(receiveValue: { _ in
            print(">> in init")
        })
        .store(in: &cancellables)
}

在这样定义的cancellables中,您可以存储在init中创建的所有订阅者,但是以后将无法在代码中使用它,但是这种方法对于一次定义的通知处理程序是有用的。

答案 1 :(得分:1)

您可以使用onAppear吗?

...
...
  var body: some View {
  ... your body code
  }.onAppear(perform: loadNotification)

  private func loadNotification() {
     NotificationCenter.default.publisher(
     ....
  }

请参见onAppear

https://developer.apple.com/documentation/swiftui/view/3278614-onappear

它似乎是viewDidLoad的替代品