在IOS Swift中检测屏幕解锁事件

时间:2016-09-29 07:41:34

标签: ios swift

如何在iPhone上检测屏幕解锁事件?当用户解锁时,我想在我的应用中执行操作。我搜索谷歌搜索但只找到与目标C相关的代码,将其更改为快速但不起作用 关注此博客: http://kidtechblogs.blogspot.com/2014/07/how-to-detect-screen-lockunlock-events.html
任何帮助如何在swift中检测到它。 下面是代码更改为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)
    }

3 个答案:

答案 0 :(得分:8)

代码示例中有一些错误:

  • 在swift中使用CFString是通过一个简单的演员来完成的:myString as CFString,不再是CFSTR() ......
  • 获取通知回调的最简单方法是使用Unmanaged.passUnretained(self).toOpaque()添加观察者。这将使您有可能在课堂上收听回调

最后,swift版本与objective-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)

答案 1 :(得分:2)

我刚刚更新了代码

只需将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")
       }

   
}




 

答案 2 :(得分:0)

据我们所知,您无法使用本机代码检测屏幕锁定解锁状态。通过使用私有api,将有机会检测屏幕锁定 - 解锁状态。如果您使用的是私人api苹果,您的应用可能会被拒绝。我们建议不要使用apple private api。

如果您想在jail broken设备中使用屏幕锁定解锁事件

,可以从以下链接中找到答案

Getting state for system wide notifications in iOS and OS X

Lock Unlock events iphone

Detect screen on/off from iOS service