How can i detect screen unlock events on iPhone? When the user unlocks it, I want to perform an action in my app. I searched on googled but only found code related to object
There a few errors in your code sample:
CFString
in swift is done by a simple cast: myString as CFString
, no more CFSTR()
...Unmanaged.passUnretained(self).toOpaque()
. That will give you the possibility to catch the callback in your class In the end, the swift version is quite different from the objective-c one, here the full code in 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")
}
}
and just in case, don't forget to remove your observer:
CFNotificationCenterRemoveObserver(CFNotificationCenterGetLocalCenter(),
Unmanaged.passUnretained(self).toOpaque(),
nil,
nil)
I just updated the Code
just call the registerforDeviceLockNotification() function into app delegate didfinishLunch function (AppDelegate.swift)
if you are using session then call the registerforDeviceLockNotification() function into willConnectTo (SceneDelegate.swift)
example code (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")
}
}
Example Code (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")
}
}
As far as we know you can't detect screen lock-unlock status by using native code. By using private api there will be chance of detecting screen lock-unlock status. Your app might be rejected if you are using private api of apple. We recommend not to use apple private api.
You can find the answer from below links if you want screen lock-unlock event in jail broken device
Getting state for system wide notifications in iOS and OS X
Lock Unlock events iphone
Detect screen on/off from iOS service