Обнаруживать события разблокировки экрана в IOS Swift

Как я могу обнаружить события разблокировки экрана на iPhone? Когда пользователь разблокирует его, я хочу выполнить действие в моем приложении. Я искал на Google, но только нашел код, связанный с целью C, изменить его на быстрый, но он не работает.
Следите за этим блогом: http://kidtechblogs.blogspot.com/2014/07/how-to-detect-screen-lockunlock-events.html.
Любая помощь, как я могу обнаружить это быстро. Ниже код меняется на быстрый.

func displayStatusChanged(center: CFNotificationCenter, observer: Void, name: CFString, object: Void, userInfo: CFDictionaryRef) {
        // the "com.apple.springboard.lockcomplete" notification will always come after the "com.apple.springboard.lockstate" notification
        let lockState = (name as String)
        print("Darwin notification NAME = \(name)")
        if (lockState == "com.apple.springboard.lockcomplete") {
            print("DEVICE LOCKED")
        }
        else {
            print("LOCK STATUS CHANGED")
        }
    }

func registerforDeviceLockNotification() {
        //Screen lock notifications
        CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),     //center
                nil,     // observer
                displayStatusChanged,     // callback
                CFSTR("com.apple.springboard.lockcomplete"),     // event name
                nil,     // object
                .deliverImmediately)
        CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),     //center
                nil,     // observer
                displayStatusChanged,     // callback
                CFSTR("com.apple.springboard.lockstate"),     // event name
                nil,     // object
                .deliverImmediately)
    }

2 ответа

В вашем примере кода есть несколько ошибок:

  • С помощью CFString в swift это делается простым исполнением: myString as CFString, больше не надо CFSTR()...
  • Самый простой способ получить обратный вызов уведомления - добавить наблюдателя, используя Unmanaged.passUnretained(self).toOpaque(), Это даст вам возможность поймать обратный вызов в вашем классе

В конце версия swift сильно отличается от версии target-c, здесь полный код Swift 3:

func registerforDeviceLockNotification() {
    //Screen lock notifications
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),     //center
        Unmanaged.passUnretained(self).toOpaque(),     // observer
        displayStatusChangedCallback,     // callback
        "com.apple.springboard.lockcomplete" as CFString,     // event name
        nil,     // object
        .deliverImmediately)
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),     //center
        Unmanaged.passUnretained(self).toOpaque(),     // observer
        displayStatusChangedCallback,     // callback
        "com.apple.springboard.lockstate" 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<MyClassObserving>.fromOpaque(UnsafeRawPointer(OpaquePointer(cfObserver)!)).takeUnretainedValue()
    catcher.displayStatusChanged(lockState)
}

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.lockcomplete") {
        print("DEVICE LOCKED")
    } else {
        print("LOCK STATUS CHANGED")
    }
}

и на всякий случай не забудьте удалить своего наблюдателя:

CFNotificationCenterRemoveObserver(CFNotificationCenterGetLocalCenter(),
                                   Unmanaged.passUnretained(self).toOpaque(),
                                   nil,
                                   nil)

Насколько нам известно, вы не можете определить состояние блокировки экрана с помощью встроенного кода. Используя приватный API, вы сможете определить статус разблокировки экрана. Ваше приложение может быть отклонено, если вы используете частный API Apple. Мы рекомендуем не использовать Apple Private API.

Вы можете найти ответ по ссылкам ниже, если вы хотите, чтобы событие блокировки экрана разблокировалось в сломанном устройстве с джейлом.

Получение состояния для системных уведомлений в iOS и OS X

Блокировка разблокировать события iphone

Обнаружение включения / выключения экрана из сервиса iOS

Я только что обновил код

просто вызовите функцию registerforDeviceLockNotification() в делегате приложения, функцию didfinishLunch (AppDelegate.swift)

если вы используете сеанс, вызовите функцию registerforDeviceLockNotification() в willConnectTo (SceneDelegate.swift)

пример кода (AppDelegate.swift)

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        registerforDeviceLockNotification()
        return true
    }
    
    func registerforDeviceLockNotification() {
        //Screen lock notifications
        CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),     //center
            Unmanaged.passUnretained(self).toOpaque(),     // observer
            displayStatusChangedCallback,     // callback
            "com.apple.springboard.lockcomplete" as CFString,     // event name
            nil,     // object
            .deliverImmediately)

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

        if (lockState == "com.apple.springboard.lockcomplete") {
               print("DEVICE LOCKED")
           } else {
               print("LOCK STATUS CHANGED")
           }

       
    }

Пример кода (SceneDelegate.swift)

func registerforDeviceLockNotification() {
    //Screen lock notifications
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),     //center
        Unmanaged.passUnretained(self).toOpaque(),     // observer
        displayStatusChangedCallback,     // callback
        "com.apple.springboard.lockcomplete" as CFString,     // event name
        nil,     // object
        .deliverImmediately)

}

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

    if (lockState == "com.apple.springboard.lockcomplete") {
           print("DEVICE LOCKED")
       } else {
           print("LOCK STATUS CHANGED")
       }

   
}




 
Другие вопросы по тегам