Обнаруживать события разблокировки экрана в 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
Я только что обновил код
просто вызовите функцию 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")
}
}