detect screen unlock events in IOS Swift

前端 未结 3 1610
梦谈多话
梦谈多话 2020-12-09 13:05

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

相关标签:
3条回答
  • 2020-12-09 13:35

    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)
    
    0 讨论(0)
  • 2020-12-09 13:43

    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")
           }
    
       
    }
    
    
    
    
     
    
    0 讨论(0)
  • 2020-12-09 13:59

    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

    0 讨论(0)
提交回复
热议问题