Recently, I tried to make a task management app that wants to identify whether my app goes into background due to user switching to another app or pressing the lock button. If he/she locks the screen, the clock goes on. Otherwise, the clock will be interrupted. However, I found out that current solutions to this problem are only applicable to iOS 7 in Objective-C. So I decided to modify it to make it up to date with the new Swift 3 syntax.
It utilizes Darwin Notifications with CFNotificationCallback method to detect lockstatus right after app goes into background. It can be achieved by adding the following code to AppDelegate.swift in four simple steps:
Add the following code right under AppDelegate class declaration
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let displayStatusChanged: CFNotificationCallback = { center, observer, name, object, info in
let str = name!.rawValue as CFString
if (str == "com.apple.springboard.lockcomplete" as CFString) {
let isDisplayStatusLocked = UserDefaults.standard
isDisplayStatusLocked.set(true, forKey: "isDisplayStatusLocked")
isDisplayStatusLocked.synchronize()
}
}
//other functions
}
Inside didFinishLaunchingWithOptions
, add the following code:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let isDisplayStatusLocked = UserDefaults.standard
isDisplayStatusLocked.set(false, forKey: "isDisplayStatusLocked")
isDisplayStatusLocked.synchronize()
// Darwin Notification
let cfstr = "com.apple.springboard.lockcomplete" as CFString
let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
let function = displayStatusChanged
CFNotificationCenterAddObserver(notificationCenter,
nil,
function,
cfstr,
nil,
.deliverImmediately)
return true
}
Inside applicationDidEnterBackground
, add the following code:
func applicationDidEnterBackground(_ application: UIApplication) {
let isDisplayStatusLocked = UserDefaults.standard
if let lock = isDisplayStatusLocked.value(forKey: "isDisplayStatusLocked"){
// user locked screen
if(lock as! Bool){
// do anything you want here
print("Lock button pressed.")
}
// user pressed home button
else{
// do anything you want here
print("Home button pressed.")
}
}
}
Inside applicationWillEnterForeground
, add the following code:
func applicationWillEnterForeground(_ application: UIApplication) {
print("Back to foreground.")
//restore lock screen setting
let isDisplayStatusLocked = UserDefaults.standard
isDisplayStatusLocked.set(false, forKey: "isDisplayStatusLocked")
isDisplayStatusLocked.synchronize()
}
Please download/clone the project for a brief demonstration.
Detecting Home button vs Lock button - iOS 7 by Jose Santiago