Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

detect screen unlock events in IOS Swift

Tags:

ios

swift

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 objective C , change it to swift but its not working.
Follow this blog: http://kidtechblogs.blogspot.com/2014/07/how-to-detect-screen-lockunlock-events.html.
Any help how can i detect it in swift. Below is the code change into swift..

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)
    }
like image 980
fmashkoor Avatar asked Sep 29 '16 07:09

fmashkoor


3 Answers

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

like image 142
Patrick R Avatar answered Nov 03 '22 23:11

Patrick R


There a few errors in your code sample:

  • Using CFString in swift is done by a simple cast: myString as CFString, no more CFSTR()...
  • The easiest way to get the notification callback is to have add an observer using 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)
like image 13
tbaranes Avatar answered Nov 03 '22 22:11

tbaranes


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")
       }

   
}




 
like image 2
Muhammad Ahmad Avatar answered Nov 03 '22 22:11

Muhammad Ahmad