调用 UIApplication 子类方法来启动调度计时器



我正在使用 Xcode 9.2/iOS 10 和 Swift 来检测 iOS 应用程序中的用户不活动,使用基于 https://blog.gaelfoppolo.com/detecting-user-inactivity-in-ios-application-684b0eeeef5b 优秀教程示例的信息 我所做的增强功能是在调用 viewDidLoad 时启动计时器,并在 applicationDidTimeout 中添加一个贪睡函数。在编译时,将显示以下错误消息:"实例成员'snoozeTimer'不能在类型'TimerApplication'上使用;你的意思是改用这种类型的值吗?

applicationDidTimeout 将使用 snoozeTimer 来控制它是否需要另一个计时器警报,具体取决于要添加到方法中的其他逻辑。

调用startTimer 和 snoozeTimer 的正确方法是什么?

代码清单如下所示:

主.swift

UIApplicationMain(
CommandLine.argc,
UnsafeMutableRawPointer(CommandLine.unsafeArgv)
.bindMemory(
to: UnsafeMutablePointer<Int8>.self,
capacity: Int(CommandLine.argc)),
NSStringFromClass(TimerApplication.self),
NSStringFromClass(AppDelegate.self)
)

应用委托.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()
}
}

定时器应用程序.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
}
}

视图控制器.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.
}

}

您希望使用TimerApplication.shared.snoozeTimer()而不是TimerApplication.snoozeTimer(),因为snoozeTimer()是实例方法,而不是类或静态方法。

您应该验证TimerApplication.shared是否返回您期望TimerApplication的实例,因为我从未像这样对系统单例进行子类化。如果这不起作用,则需要一种方法来获取对所需TimerApplication实例的引用。

最新更新