首页 > 解决方案 > 当应用程序在后台时如何使用计时器

问题描述

我使用 Timer 每 4 秒调用一个函数

如果我点击同一个 viewController 中的一个按钮,我就会导航到谷歌地图。

导航到谷歌地图后,该函数没有被调用

这是通过按钮操作

@IBAction func navigateBtnClicked(_ sender: Any) {
    if UIApplication.shared.canOpenURL(URL(string: "comgooglemaps://")!) {
        let googleMapUrlString: String = "comgooglemaps://?saddr=&daddr=\(CDouble(pickupLat)),\(CDouble(pickupLong))&mode=driving"
        UIApplication.shared.open(URL(string: googleMapUrlString)!, options: [:], completionHandler: nil)
    }
}

这是我使用计时器的代码

override func viewDidLoad() {
    super.viewDidLoad()

    DispatchQueue.global(qos: .default).async(execute: {
        sendingLatLongTimer = Timer(timeInterval: 4, target: self, selector: #selector(self.webserviceCall), userInfo: nil, repeats: true)
        RunLoop.main.add(self.sendingLatLongTimer!, forMode: .commonModes)
    })
}

标签: swiftgoogle-mapsnstimerdispatchertimer

解决方案


实际上您可以在后台使用 Timer,但您必须先创建 BackgroundTask,然后才能看到这里的要点:https ://gist.github.com/phatmann/e96958529cc86ff584a9 应注意 IOS 11 中的后台任务最长寿命为 180 秒,后台任务到期后,您的应用程序进入挂起模式,如果您需要定期在后台执行某些工作,请使用服务器的静默推送。

private func startBarkgroundTaskTimer(time: TimeInterval) {
    backgroundTaskTimer?.invalidate()
    backgroundTaskTimer = nil
    backgroundTaskTimer = Timer.scheduledTimer(
        withTimeInterval: time,
        repeats: true,
        block: { [weak self] _ in
            guard let `self` = self, UIApplication.isBackground else { return }
            Logger.log("update location from BG")
    })
}

推荐阅读