【发布时间】:2020-01-02 21:28:54
【问题描述】:
我正在使用 Xcode 9.2/iOS 10 和 Swift 来检测用户在 iOS 应用程序中的不活动,使用基于来自 https://blog.gaelfoppolo.com/detecting-user-inactivity-in-ios-application-684b0eeeef5b 的优秀教程示例的信息我所做的增强是在调用 viewDidLoad 时启动计时器并添加贪睡applicationDidTimeout 中的函数。在编译时,会显示以下错误消息:“Instance member 'snoozeTimer' cannot be used on type '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.
}
}
【问题讨论】:
-
解决了吗?有同样的问题..任何帮助将不胜感激。!
标签: ios swift nstimer uiapplicationdelegate uiapplication