How do I add NotificationCenter.default.addObserve in SwiftUI?
When I tried adding observer I get below error
Argument of '#selector' refers to instance method 'VPNDidChangeStatus' that is not exposed to Objective-C
But when I add @objc in front of func I get below error
@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes
Here is my code
let NC = NotificationCenter.default var body: some View { VStack() { }.onAppear { self.NC.addObserver(self, selector: #selector(self.VPNDidChangeStatus), name: .NEVPNStatusDidChange, object: nil) } } @objc func VPNDidChangeStatus(_ notification: Notification) { // print("VPNDidChangeStatus", VPNManager.shared.status) }
The accepted answer may work but is not really how you're supposed to do this. In SwiftUI you don't need to add an observer in that way.
You add a publisher and it still can listen to NSNotification events triggered from non-SwiftUI parts of the app and without needing combine.
Here as an example, a list will update when it appears and when it receives a notification, from a completed network request on another view / controller or something similar etc.
If you need to then trigger an @objc func for some reason, you will need to create a Coordinator
with UIViewControllerRepresentable
struct YourSwiftUIView: View { let pub = NotificationCenter.default .publisher(for: NSNotification.Name("YourNameHere")) var body: some View { List() { ForEach(userData.viewModels) { viewModel in SomeRow(viewModel: viewModel) } } .onAppear(perform: loadData) .onReceive(pub) { (output) in self.loadData() } } func loadData() { // do stuff } }
I have one approach for NotificationCenter
usage in SwiftUI
.
For more information Apple Documentation
Notification extension
extension NSNotification { static let ImageClick = Notification.Name.init("ImageClick") }
ContentView
struct ContentView: View { var body: some View { VStack { DetailView() } .onReceive(NotificationCenter.default.publisher(for: NSNotification.ImageClick)) { obj in // Change key as per your "userInfo" if let userInfo = obj.userInfo, let info = userInfo["info"] { print(info) } } } }
DetailView
struct DetailView: View { var body: some View { Image(systemName: "wifi") .frame(width: 30,height: 30, alignment: .center) .foregroundColor(.black) .onTapGesture { NotificationCenter.default.post(name: NSNotification.ImageClick, object: nil, userInfo: ["info": "Test"]) } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With