我正在使用Xcode 9.2 / iOS 10和Swift,根据来自https://blog.gaelfoppolo.com/detecting-user-inactivity-in-ios-application-684b0eeeef5b的出色教程示例的信息来检测iOS应用程序中的用户不活动状态,我所做的增强功能是在调用viewDidLoad时启动计时器并添加applicationDidTimeout中的贪睡功能。在编译时,将显示以下错误消息:“实例成员'snoozeTimer'不能用于'TimerApplication'类型;您是要使用此类型的值吗?”
applicationDidTimeout将使用snoozeTimer来控制是否需要另一个计时器警报,具体取决于要添加到该方法的其他逻辑。
调用startTimer和snoozeTimer的正确方法是什么?
代码清单如下所示:
main.swift
UIApplicationmain(
CommandLine.argc,UnsafeMutableRawPointer(CommandLine.unsafeArgv)
.bindMemory(
to: UnsafeMutablePointer<Int8>.self,capacity: Int(CommandLine.argc)),NSStringFromClass(TimerApplication.self),NSStringFromClass(AppDelegate.self)
)
AppDelegate.swift
import UIKit
import Foundation
extension Notification.Name {
static let appTimeout = Notification.Name("appTimeout")
}
//@UIApplicationmain
class AppDelegate: UIResponder,UIApplicationDelegate {
var window: UIWindow?
var backgroundTaskRunCount : Int = 0
func application(_ application: UIApplication,didFinishlaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
NotificationCenter.default.addobserver(self,selector: #selector(AppDelegate.applicationDidTimeout(notification:)),name: .appTimeout,object: nil
)
return true
}
. //other func
.
.
@objc func applicationDidTimeout(notification: Nsnotification) {
backgroundTaskRunCount = backgroundTaskRunCount + 1
print("application did timeout,perform actions. Count=",backgroundTaskRunCount)
TimerApplication.snoozeTimer()
}
}
TimerApplication.swift
import UIKit
class TimerApplication: UIApplication {
private var wakeupInSeconds: TimeInterval {
// 2 minutes for for timer to fire first time
return 2 * 60
}
private let snoozeInSeconds: TimeInterval = 5
// the timeout in seconds,after which should perform custom actions
// such as disconnecting the user
private var timeoutInSeconds: TimeInterval = 120
private var idleTimer: Timer?
// resent the timer because there was user interaction
private func resetIdleTimer() {
if timeoutInSeconds > 0 {
if let idleTimer = idleTimer {
idleTimer.invalidate()
}
idleTimer = Timer.scheduledTimer(timeInterval: timeoutInSeconds,target: self,selector: #selector(TimerApplication.timeHasExceeded),userInfo: nil,repeats: false
)
} else {
stopTimer()
}
}
// if the timer reaches the limit as defined in timeoutInSeconds,post this notification
@objc private func timeHasExceeded() {
NotificationCenter.default.post(name: .appTimeout,object: nil
)
}
override func sendEvent(_ event: UIEvent) {
super.sendEvent(event)
if idleTimer != nil {
self.resetIdleTimer()
}
if let touches = event.allTouches {
for touch in touches where touch.phase == UITouchPhase.began {
self.resetIdleTimer()
}
}
}
func startTimer() {
self.timeoutInSeconds = wakeupInSeconds
self.resetIdleTimer()
}
func stopTimer() {
if let idleTimer = idleTimer {
idleTimer.invalidate()
}
}
func snoozeTimer() {
self.timeoutInSeconds = snoozeInSeconds
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view,typically from a nib.
TimerApplication.startTimer()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}