How can I detect screen lock/unlock events on the iPhone? How can I detect screen lock/unlock events on the iPhone? ios ios

How can I detect screen lock/unlock events on the iPhone?


Check this out, I wanted to detect the lock/unlock events, I solved it by Darwin notifications.You can detect the event when the device is locked by "com.apple.springboard.lockcomplete".

//call backstatic void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo){    // the "com.apple.springboard.lockcomplete" notification will always come after the "com.apple.springboard.lockstate" notification    NSString *lockState = (NSString*)name;    NSLog(@"Darwin notification NAME = %@",name);    if([lockState isEqualToString:@"com.apple.springboard.lockcomplete"])    {        NSLog(@"DEVICE LOCKED");    }    else    {        NSLog(@"LOCK STATUS CHANGED");    }   }-(void)registerforDeviceLockNotif{    //Screen lock notifications    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center                                    NULL, // observer                                    displayStatusChanged, // callback                                    CFSTR("com.apple.springboard.lockcomplete"), // event name                                    NULL, // object                                    CFNotificationSuspensionBehaviorDeliverImmediately);    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center                                    NULL, // observer                                    displayStatusChanged, // callback                                    CFSTR("com.apple.springboard.lockstate"), // event name                                    NULL, // object                                    CFNotificationSuspensionBehaviorDeliverImmediately);  }   


To detect lock/unlock inside app in swift 5 only this worked for me:

override func viewDidLoad() {    super.viewDidLoad()     NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive), name: UIApplication.willEnterForegroundNotification, object: nil)     NotificationCenter.default.addObserver(self, selector: #selector(applicationDidEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)}@objc func applicationDidBecomeActive(notification: NSNotification) {    print("ACTIVE")}@objc func applicationDidEnterBackground(notification: NSNotification) {    print("BACKGROUND")}


  1. You can't use com.apple.springboard.lockcomplete or com.apple.springboard.lockstate when submitting your app to App Store, your app will be rejected because it's private API.

  2. The com.apple.springboard.lockcomplete notification NOT always comes after the com.apple.springboard.lockstate notification, it may happen early or later. You need to set a timer to wait for that event.

So here is how you can detect screen lock and unlock status, in Swift 5:

struct NotificationName {    // Listen to CFNotification, and convert to Notification    public static let lockComplete = Notification.Name("NotificationName.lockComplete")    public static let lockState = Notification.Name("NotificationName.lockState")    // Handle lockComplete and lockState Notification to post locked or unlocked notification.    public static let locked = Notification.Name("NotificationName.locked")    public static let unlocked = Notification.Name("NotificationName.unlocked")}func addNotificationObservers() {    let lockCompleteString = "com.apple.springboard.lockcomplete"    let lockString = "com.apple.springboard.lockstate"    // Listen to CFNotification, post Notification accordingly.    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),                                    nil,                                    { (_, _, _, _, _) in                                        NotificationCenter.default.post(name: NotificationName.lockComplete, object: nil)                                    },                                    lockCompleteString as CFString,                                    nil,                                    CFNotificationSuspensionBehavior.deliverImmediately)    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),                                    nil,                                    { (_, _, _, _, _) in                                        NotificationCenter.default.post(name: NotificationName.lockState, object: nil)                                    },                                    lockString as CFString,                                    nil,                                    CFNotificationSuspensionBehavior.deliverImmediately)    // Listen to Notification and handle.    NotificationCenter.default.addObserver(self,                                            selector: #selector(onLockComplete),                                            name: NotificationName.lockComplete,                                            object: nil)    NotificationCenter.default.addObserver(self,                                            selector: #selector(onLockState),                                            name: NotificationName.lockState,                                            object: nil)}// nil means don't know; ture or false means we did or did not received such notification.var receiveLockStateNotification: Bool? = nil// when we received lockState notification, use timer to wait 0.3s for the lockComplete notification.var waitForLockCompleteNotificationTimer: Timer? = nilvar receiveLockCompleteNotification: Bool? = nil// When we received lockComplete notification, invalidate timer and refresh lock status.@objcfunc onLockComplete() {    if let timer = waitForLockCompleteNotificationTimer {        timer.invalidate()        waitForLockCompleteNotificationTimer = nil    }    receiveLockCompleteNotification = true    changeIsLockedIfNeeded()}// When we received lockState notification, refresh lock status.@objcfunc onLockState() {    receiveLockStateNotification = true    changeIsLockedIfNeeded()}func changeIsLockedIfNeeded() {    guard let state = receiveLockStateNotification, state else {        // If we don't receive lockState notification, return.        return    }    guard let complete = receiveLockCompleteNotification else {        // If we don't receive lockComplete notification, wait 0.3s.        // If nothing happens in 0.3s, then make sure we don't receive lockComplete, and refresh lock status.        waitForLockCompleteNotificationTimer = Timer.scheduledTimer(withTimeInterval: 0.3, repeats: false, block: { _ in            self.receiveLockCompleteNotification = false            self.changeIsLockedIfNeeded()        })        return    }    // When we determined lockState and lockComplete notification is received or not.    // We can update the device lock status by 'complete' value.    NotificationCenter.default.post(        name: complete ? NotificationName.locked : NotificationName.unlocked,        object: nil    )    // Reset status.    receiveLockStateNotification = nil    receiveLockCompleteNotification = nil}