Операторы повторяющихся событий CFNotificationCenter

Я работаю над корпоративным приложением iOS/Swift (iOS 11.3, Xcode 9.3.1), в котором я хочу получать уведомления, если экран изменяется (становится пустым или становится активным) и фиксирует события в базе данных Realm. Я использую ответ от tbaranes в обнаружении событий разблокировки экрана в IOS Swift и это работает, но я нахожу добавленные повторы, когда экран гаснет и становится активным:

  • Initial Blank: записано одно событие
  • Начальная повторная активация: фиксируются два события

  • Второй бланк: записываются два события.

  • Второй реакт: фиксируются три события

    и этот цикл добавления дополнительного события, записывающего каждый цикл.

Это должно быть что-то в коде (или отсутствующее в коде), что вызывает аддитивный эффект, но я не могу его найти. И да, операторы печати показывают, что проблема не в базе данных Realm, а являются фактически повторяющимися операторами.

Мой код ниже. Любые предложения приветствуются.

 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

    }

person RLW    schedule 20.05.2018    source источник
comment
Где этот код? Что за объект? Какой? Вы звоните CFNotificationCenterRemoveObserver()? Ваш объект deinit/релиз? Где именно называется CFNotificationCenterAddObserver()   -  person Larme    schedule 20.05.2018
comment
Спасибо за ваши вопросы, я должен был быть более ясным. У меня это вызывается в функции applicationDidEnterBackground, и приложение остается активным во время его использования (т.е. даже в фоновом режиме). Я намерен использовать это на протяжении всей операции в фоновом режиме, поэтому у меня нет deinit/release, поскольку я не знаю, как в противном случае сохранить непрерывное использование функции.   -  person RLW    schedule 20.05.2018
comment
Некоторые дополнительные исследования и явления, описанные в исходном посте, происходят только при ручной блокировке экрана. В противном случае количество уведомлений остается постоянным на текущем уровне (который может быть больше обычного из-за ручной блокировки).   -  person RLW    schedule 21.05.2018
comment
Еще немного поработал, и я обнаружил, что дважды вызывал CFNotifications, и это вызывало повторяющиеся уведомления. Спасибо Ларме и всем, кто читал и размышлял.   -  person RLW    schedule 21.05.2018