美文网首页
后台时不暂停的倒计时

后台时不暂停的倒计时

作者: 悃破 | 来源:发表于2018-06-05 12:13 被阅读58次

背景:
注册页面或去验证码倒计时功能,如果进入后台后倒计时停止,产品希望即使进入后台后倒计时仍然不会停止。

定时器代码

public class Timer: NSObject {

    deinit {
        //如果外面不持有会立刻释放,但仍然会倒计时
        print("释放了")
    }
    
    public var sourceTimer: DispatchSourceTimer?
    private var backgroundTaskIdentifier: UIBackgroundTaskIdentifier?
    private var duration: TimeInterval
    private var interval: TimeInterval
    private var intervalBlock: (() -> Void)?
    private var endBackgroundBlock: (() -> Void)?
    private var completeBlock: (() -> Void)?
    
    init(duration: TimeInterval, interval: TimeInterval, intervalBlock: (() -> Void)?, endBackgroundBlock: (() -> Void)?, completeBlock: (() -> Void)?) {
        self.duration = duration
        self.interval = interval
        self.intervalBlock = intervalBlock
        self.endBackgroundBlock = endBackgroundBlock
        self.completeBlock = completeBlock
    }
    
    public func start() {
        var time = self.duration
        let sourceTimer = DispatchSource.makeTimerSource()
        sourceTimer.schedule(deadline: .now(), repeating: self.interval, leeway: .seconds(1))
        sourceTimer.setEventHandler {
            
            if time <= 0 {
                sourceTimer.cancel()
                DispatchQueue.main.async {
                    self.completeBlock?()
                }
                self.endBackGroundTask()
            } else {
                time -= self.interval
                DispatchQueue.main.async {
                    self.intervalBlock?()
                }
            }
        }
        sourceTimer.resume()
        self.backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: {
            //当程序被挂起时执行这个函数
            self.endBackgroundBlock?()
            self.endBackGroundTask()
        })
        self.sourceTimer = sourceTimer
        
    }
    
    public func cancel() {
        self.sourceTimer?.cancel()
        self.endBackGroundTask()
    }
    
    private func endBackGroundTask() {
        if let id = backgroundTaskIdentifier {
            UIApplication.shared.endBackgroundTask(id)
            self.backgroundTaskIdentifier = UIBackgroundTaskInvalid
        }
    }
    
}

使用:

@IBAction func btnClick(_ sender: UIButton) {
        sender.setTitle("\(10)", for: .normal)
        sender.isEnabled = false
        var time = 10
        Timer(duration: Double(time), interval: 1, intervalBlock: {
            sender.setTitle("\(time)", for: .normal)
            time -= 1
        }, endBackgroundBlock: nil) {
            sender.setTitle("获取验证码", for: .normal)
            sender.isEnabled = true
        }.start()
    }

关键字: iOS 倒计时 后台 计时器 Timer

相关文章

网友评论

      本文标题:后台时不暂停的倒计时

      本文链接:https://www.haomeiwen.com/subject/pabjjftx.html