iOS后台任务检测屏幕打开或关闭

我正在开发一个记录屏幕开/关事件的应用程序.这是一种智能手机使用分析应用程序.所有的应用程序都是写下这样的日志:

2015 July 25 at 03:54:12 PM - Screen on
2015 July 25 at 03:59:38 PM - Screen off
2015 July 25 at 04:20:52 PM - Screen on
2015 July 25 at 04:22:32 PM - Screen off
...
2015 July 26 at 10:20:32 AM - Screen on
2015 July 26 at 10:22:11 AM - Screen off
2015 July 26 at 11:30:38 AM - Screen on
2015 July 26 at 10:31:02 AM - Screen off
...

>“屏幕开启”:用户按下主页按钮(或电源按钮)并输入密码/解锁密码(如果有).
>“屏幕关闭”:用户按电源按钮关闭屏幕.

我能够在Android上使用广播接收器找到一些方法来捕获系统发送的事件.但是在iOS中似乎存在一个问题,因为iOS只允许后台服务运行几分钟,我甚至不确定我是否可以在iOS上检测到“屏幕开/关”事件.

我做了一些关于这方面的研究,发现了一些文章,但那些没有多大帮助:

> http://www.macworld.com/article/1164616/how_ios_multitasking_really_works.html
> Lock Unlock events iphone

我的问题是“是否可以在iOS中制作这样的应用程序(最新版本 – 8.4)?”

谢谢.

最佳答案 使用后台服务可能无法满足已发布的非监狱iOS设备的所有要求.我可以看到通知发生,我只是不确定背景.

由于其他人一直在说这是不可能的,我在这里挖掘一下,看看能做多少.

由于iOS目前仅限于少数背景模式(事件在后台传递的情况),或者在用户导航离开应用程序后几分钟内授予应用程序的模式,因此主要问题是欺骗系统让你的应用程序在需要时在后台获得时间.

有一些后台模式,如Programming Guide to Background Execution中所述.例如,如果您可以定期发送推送通知以唤醒应用程序“下载内容”,您可以定期获得一些时间,因为系统认为适合这样做.

后台Daemon是一个可能的解决方案,但仅供您自己使用,但不能通过App Store.官方对此是在App Store Review Guidelines – 相关部分是2.8(可能是你通过让应用程序“在幕后”安装它来获得你的守护进程):

2.8 Apps that install or launch other executable code will be rejected

iOS可能会保留一些系统日志;如果您可以访问这些,那么您就拥有了自己的数据.但是,我怀疑这是从一个非监狱破坏的手机以编程方式提供的.

我能够测试一些Swift(2.0)代码,它使用了一个Stack Overflow讨论中提到的Darwin Notifications,原始问题导致了:Lock / Unlock Events for iPhone.我实际上并没有在后台运行,但我确实验证了即使应用程序在实际锁定事件发生时未运行,最终也会传递事件.当我的应用程序被切换时,通知被调用.因此,如果您能够从系统中获得时间,那么当Apple的算法决定给您时间时,您会收到(延迟)通知.

允许监听的代码片段(我将其填入一些随机应用程序)如下:

import UIKit
import CoreFoundation

class MainViewController: UIViewController, UIWebViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // CoreFoundation compatible types
        var cfstr: CFString = "com.apple.iokit.hid.displayStatus" as NSString
        var notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()

        CFNotificationCenterAddObserver(notificationCenter, nil,
            { (noti: CFNotificationCenter!, aPtr: UnsafeMutablePointer<Void>, aStr: CFString!, bPtr: UnsafePointer<Void>, aDict: CFDictionary!) -> () in
                print("got notification") }, cfstr, nil, CFNotificationSuspensionBehavior.DeliverImmediately)

    }
    // [... more stuff ...]
}
点赞