user10816637
user10816637

Reputation: 7

I don't understand why my object doesn't receive notifications

I've create a custom class that looks like:

class FooDevice: Device {

  private var controller:FooController?
  private var device:Foo?


  override init() {
    super.init()
    if super.authGranted {
      NotificationCenter.default.addObserver(self, selector: #selector(self.discovered(_:)), name: NSNotification.Name(rawValue: FooDiscover), object: nil)
      NotificationCenter.default.addObserver(self, selector: #selector(self.connected(_:)), name: NSNotification.Name(rawValue: FooConnected), object: nil)
    }
  }

  @objc private func discovered(_ notification:Notification) {
    DDLogVerbose("FOO - discovered - \(notification)")
    super.scanner?.stopScanFor(._FOO)
    // TODO: Call super.connector and connect
  }

  @objc private func connected(_ notification:Notification) {
    DDLogVerbose("FOO - connected - \(notification)")
    // Do more stuff after connect
  }


  func start() {
    DDLogVerbose("FOO - startMeasurement()")
    super.scanner?.scanFor(._FOO)
  }  
}

The super class looks like:

class Device: NSObject {

  private let LICENSE = "my_license"

  private var authenticator:SDKAuthenticator?
  internal var scanner:SDKScanner?
  internal var connector:SDKConnector?
  internal var authGranted = false


  override init() {
    super.init()
    authGranted = self.authRequest(LICENSE)
    if authGranted {
      scanner = SDKScanner.getInstance()
      connector = SDKConnector.getInstance()
    } else {
      // TODO: Show error to user
    }
  }

  private func authRequest(_ data:String) -> Bool {
    // Do stuff using authenticator and authenticated, we can assume we return a true
    return status // true
  }
}

In my ViewController I make an instance of FooDevice and start the process. I'm doing with the following:

class MyViewController:UIViewController {

 // A lot of properties
 override viewDidLoad() {
   // ViewDidLoad stuff
 }

 @IBAction func connectToDevice(_ sender: Any) {
  // Here I instantiate the object and start the scanning
  let myFooDevice = FooDevice()
  myFooDevice.start()
 }
}

In the console I could see how the scanner start and found the bluetooth device but the notification isn't captured and the log isn't printed. Also the notification names are right, I'm sure because the SDK return the strings.

I don't know what I'm missing. Hope you could throw some light to it.

Upvotes: 0

Views: 38

Answers (1)

Andreas Oetjen
Andreas Oetjen

Reputation: 10199

Your problem is that ARC will cleanup your myFooDevice variable before any notification can reach it.

You better store it in a property:

class MyViewController:UIViewController {

    var myFooDevice:FooDevice?

    override viewDidLoad() {
       // ViewDidLoad stuff
    }

    @IBAction func connectToDevice(_ sender: Any) {
        // Here I instantiate the object and start the scanning
        myFooDevice = FooDevice()
        myFooDevice!.start()
    }
}

Upvotes: 2

Related Questions