I am developing an app that logs down the screen on/off events. It's a kind of smartphone usage analysis app. All the app does is to write down a log like this:
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
...
I was able to find some way to do this this on Android using the broadcast receiver to capture the events sent by the system. But in iOS there seems to be a problem since iOS only allows background services to run several minutes, I am not even sure if I can detect the "screen on/off" event on iOS.
I did some researches on this and found some articles, but those weren't help much:
My question is "Is it possible to make an app like this in iOS (latest version - 8.4) ?"
Thanks.
It may not be possible to meet all your requirements within the published, non jail broken iOS device using the background service. I can see the notifications come across, I'm just not sure about the backgrounding.
Since others have been saying it's not possible, I'm digging a little deeper here to see just how much can be done.
Because iOS is currently restricted to a small number of background modes (situations where events are delivered in the background), or a mode where your app is granted a few minutes of time after the user navigates away from your app, the primary issue is going to be tricking the system into allowing your app to get time in the background when needed.
There are several background modes, described in the Programming Guide to Background Execution. If you can, for example, send push notifications periodically to awaken the app to "download content", you may be able to get some time periodically as the system sees fit to do so.
The background Daemon is a possible solution, but only for your own use, but not via the App Store. The official take on this is in the App Store Review Guidelines -- the relevant section is 2.8 (presumably you'd get your daemon on by having the app install it "behind the scenes"):
2.8 Apps that install or launch other executable code will be rejected
There may be some system logs that iOS keeps for itself; if you can gain access to those, you'd have your data. I doubt, however, that this is available programmatically from a non jail broken phone.
I was able to test out some Swift (2.0) code that uses the Darwin Notifications mentioned in one of the Stack Overflow discussions that your original question led to: Lock / Unlock Events for iPhone. I didn't actually run in the background, but I did verify that the events are eventually delivered, even if the app isn't running when the actual lock event takes place. When my app is switched in, the notification gets called. So, if you were able to get time from the system, you'd get the (delayed) notification when Apple's algorithms decide to give you time.
The code snippet (I stuffed it into some random app) that allows the listening is as follows:
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 ...]
}