即使应用程序最小化,也可以每分钟持续运行UIButton

时间:2018-11-13 23:25:06

标签: ios swift

当应用程序最小化时,我试图每分钟运行一次UIButton。因此,我编写了ScheduledTimer函数以在Appdelegate中每1分钟运行一次按钮,但是它不起作用,错误显示developeLocationHistoryButton:]: unrecognized selector sent to instance 0x60000024ee80。请给我一些指导。我的代码如下所示。

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {

    var window: UIWindow?
    var backgroundUpdateTask: UIBackgroundTaskIdentifier!
    var backgroundTaskTimer: Timer! = Timer()

    func doBackgroundTask() {
        DispatchQueue.global(qos: .default).async {
            self.beginBackgroundTask()
            if self.backgroundTaskTimer != nil {
                self.backgroundTaskTimer.invalidate()
                self.backgroundTaskTimer = nil
            }

            //Making the app to run in background forever by calling the API
            self.backgroundTaskTimer = Timer.scheduledTimer(timeInterval: 60, target:self , selector: #selector(ViewController.HistoryButton(_:)), userInfo: nil, repeats: true)
            RunLoop.current.add(self.backgroundTaskTimer, forMode: RunLoopMode.defaultRunLoopMode)
            RunLoop.current.run()
            self.endBackgroundTask()
        }
    }
    func beginBackgroundTask() {
        self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(withName: "test7", expirationHandler: {
            self.endBackgroundTask()
        })
    }
    func endBackgroundTask() {
        UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
        self.backgroundUpdateTask = UIBackgroundTaskInvalid
    }

我在ApplicationDidEnterBackground中添加了self.doBackgroundTask(),在ApplicationWillEnterForeground中添加了

if self.backgroundTaskTimer != nil {
        self.backgroundTaskTimer.invalidate()
        self.backgroundTaskTimer = nil

2 个答案:

答案 0 :(得分:2)

您无法做您想做的事情。如果您使用UIApplication的{​​{1}}方法请求背景时间,您将获得3分钟的时间,然后您的应用将被暂停。您能做的最好的事情就是让您的应用的计时器运行3分钟。

您的代码有很多错误。

您尝试添加一个目标为beginBackgroundTask(withName:expirationHandler:)且选择器为self的Timer,但是:

当前类是AppDelegate类,它没有名为ViewController.HistoryButton(_:)的方法。 (还请注意,方法名称应以小写字母开头。)

另一件事。这段代码:

HistoryButton(_:)

毫无意义。没有理由在该代码中创建一个Timer。将其设为可选,并且不为其分配计时器:

var backgroundTaskTimer: Timer! = Timer()

如果您使用var backgroundTaskTimer: Timer? 创建计时器,则无需将其添加到当前运行循环中,因此,请删除以scheduledTimer()开始的行和以{{1 }}

另一件事:为什么您在开始后台任务后立即致电Runloop.current

您的代码还有其他问题,但这只是一个开始。从根本上来说是有缺陷的。您正在尝试解决您显然还没有完全掌握的事情。我建议放慢脚步,慢慢学习您要尝试做的事情。

答案 1 :(得分:2)

您收到的错误表示您正在尝试对未实现该方法的对象调用方法。您的问题出在这行

Timer.scheduledTimer(timeInterval: 60, target:self , selector: #selector(ViewController.HistoryButton(_:)), userInfo: nil, repeats: true)

恰好有target: self, selector: #selector(ViewController.HistoryButton(_:))部分。 selfAppDelegate的实例,您正在给计时器打电话以在其上调用名为HistoryButton(_:)的方法。但是该方法是在类型ViewController的对象上定义的-在选择器中已明确说明。

要解决您的问题,您可以

  1. 实例化ViewController并将其作为target传递-不建议这样做,因为这容易产生副作用。
  2. 将方法复制到AppDelegate并更新选择器参数-更好,但是您重复了代码,并且需要在两个地方都进行更新。
  3. 将方法提取到外部类并在两个地方(AppDelegateViewController)都使用它