0

I have been working on an enterprise iOS/Swift (iOS 11.3, Xcode 9.3.1) app in which I want to be notified if the screen changes (goes blank or becomes active) and capture the events in a Realm databse. I am using the answer from tbaranes in detect screen unlock events in IOS Swift and it works, but I find added repeats as the screen goes blank and becomes active:

  • Initial Blank: a single event recorded
  • Initial Re-activiation: two events are recorded

  • Second Blank: two events are recorded

  • Second Re-act: three events are recorded

    and this cycle of adding an additional event recording each cycle.

This must be something in the code (or missing from the code) that is causing an additive effect but I can’t find it. And, yes, the print statements show the issue is not within the Realm database, but are actual repeated statements.

My code is below. Any suggestions are appreciated.

 CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),     //center
        Unmanaged.passUnretained(self).toOpaque(),     // observer
        displayStatusChangedCallback,     // callback
        "com.apple.springboard.hasBlankedScreen" as CFString,    // event name
        nil,     // object
        .deliverImmediately)

}

private let displayStatusChangedCallback: CFNotificationCallback = { _, cfObserver, cfName, _, _ in
    guard let lockState = cfName?.rawValue as String? else {
        return
    }

    let catcher = Unmanaged<AppDelegate>.fromOpaque(UnsafeRawPointer(OpaquePointer(cfObserver)!)).takeUnretainedValue()
    catcher.displayStatusChanged(lockState)

    print("how many times?")
}

private func displayStatusChanged(_ lockState: String) {


    // the "com.apple.springboard.lockcomplete" notification will always come after the "com.apple.springboard.lockstate" notification
    print("Darwin notification NAME = \(lockState)")

    if lockState == "com.apple.springboard.hasBlankedScreen" {

        print("A single Blank Screen")

        let statusString = dbSource() // Realm database 

        statusString.infoString = "blanked screen"
        print("statusString: \(statusString)")

        statusString.save()

        return

    }
RLW
  • 1
  • 2
  • Where is that code? What's the object? What kind? Do you call `CFNotificationCenterRemoveObserver()`? Is your object `deinit`/release? Where is called exactly `CFNotificationCenterAddObserver()` – Larme May 20 '18 at 04:41
  • Thanks for your questions, I should have been more clear. I have this called in the applicationDidEnterBackground function and the app stays live during its use (i.e., even in the background). My intent is to use this throughout the operation while in the background, so I do not have a deinit/release as I do not know how to keep the continuous use of the function otherwise. – RLW May 20 '18 at 12:43
  • Some additional investigation and the phenomena described in the original post only happens when the screen is locked manually. Otherwise, the number of notifications remains consistent at the current level (which may be greater than normal due to manual locks). – RLW May 20 '18 at 22:25
  • Some further work and I found that I was calling the CFNotifications twice, and that was causing the repeated notifications. Thanks to Larme and any others who read and pondered. – RLW May 21 '18 at 00:07

0 Answers0