Swift: Can't change class attribute from @objc function

57 Views Asked by At

I'm trying to capture ProximitySensor activity on SwiftUI. So I've created a class ProximityOberver and trying to update the attribute 'state' in the notification:

import SwiftUI
import UIKit

class ProximityObserver {
    @State var state = false;
    
    @objc func didChange(notification: NSNotification) {
        print("MyView::ProximityObserver.didChange")
        if let device = notification.object as? UIDevice {
            print(device.proximityState)
            state = device.proximityState
            print(state)
        }
    }
}

struct ContentView: View {
    @State var proximityObserver = ProximityObserver()
        
    func activateProximitySensor() {
        print("MyView::activateProximitySensor")
        if !UIDevice.current.isProximityMonitoringEnabled {
            UIDevice.current.isProximityMonitoringEnabled = true
            
            if UIDevice.current.isProximityMonitoringEnabled {
                NotificationCenter.default.addObserver(proximityObserver, selector: #selector(proximityObserver.didChange), name: UIDevice.proximityStateDidChangeNotification, object: UIDevice.current)
            }
        }
    }
    
    func deactivateProximitySensor() {
        print("MyView::deactivateProximitySensor")
        UIDevice.current.isProximityMonitoringEnabled = false
        NotificationCenter.default.removeObserver(proximityObserver, name: UIDevice.proximityStateDidChangeNotification, object: UIDevice.current)
    }

    var body: some View {
        Text(proximityObserver.state ? "true" : "false" )
                .animation(.linear(duration: 20).delay(20), value: proximityObserver.state)
        .onAppear() {
            self.activateProximitySensor()
        }
        .onDisappear() {
            self.deactivateProximitySensor()
        }
  }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

But even 'state = device.proximityState' code executed, the following print(state) shows the attribute never changed.

MyView::ProximityObserver.didChange
true
false

Can someone explain why this happens, and how to fix this?

1

There are 1 best solutions below

0
user1329928 On

Thank you for the comment. I could fix this as suggested.

class ProximityObserver: ObservableObject {
    @Published var state = false;
    
    @objc func didChange(notification: NSNotification) {
        print("MyView::ProximityObserver.didChange")
        if let device = notification.object as? UIDevice {
            print(device.proximityState)
            self.state = device.proximityState
            
            print(state, device.proximityState)
        }
    }
}

struct ContentView: View {
    @ObservedObject var proximityObserver = ProximityObserver()
...