【问题标题】:Is it possible to schedule a function to run at a specific time是否可以安排功能在特定时间运行
【发布时间】:2018-01-31 03:26:30
【问题描述】:

一直在研究这个主题,想知道是否可以将函数安排在特定时间运行,就像您可以安排本地通知在特定时间触发一样。即使应用程序已关闭或在后台运行,也需要它来运行。

用例:

我正在开发一个应用程序,该应用程序当前每天向用户发送一条随机消息“来自一系列可能的消息”作为本地通知。此本地通知在用户从日期选择器指定的特定时间触发。即使应用程序关闭,所有这些都按预期工作。

现在我正在尝试找出一种方法来显示应用程序内收到的最后一个随机通知的内容。我想为本地通知的 body.content “随机消息”设置一个标签文本......但只有在他们收到通知之后。我不想在它交付之前在应用程序中显示它。示例:用户打开应用程序,将本地通知时间设置为下午 3 点。用户关闭应用程序,下午 3 点收到通知,他们在下午 4 点打开应用程序,应用程序内的标签显示与他们收到的通知相同的消息。由于本地通知设置为重复,应用程序中的消息应保持不变,直到第二天下午 3 点。

问题,显然您无法检索已传递的本地通知的内容。这就是为什么我想知道是否可以在特定时间安排功能。如果是这样,我可以将生成的消息保存为用户默认值,然后在 5 秒内触发 UNTimeIntervalNotification 并使用相同的保存值。打开应用程序后,我可以使用保存的值更新 label.text。这样,他们每次打开应用时,应用中的标签始终与上次收到的通知相同。

我是 swift 语言的新手,非常感谢任何其他关于此问题可能解决方案的建议。

【问题讨论】:

  • “即使应用程序已关闭或在后台运行,也需要运行它。”这没有技术意义。
  • 此外,您甚至没有指定您的开发平台。
  • 更新了更多细节,不知道怎么没有意义,你能解释一下吗?或者提供解决方案?
  • 你在尝试做的事情上走错路了。您可以在应用程序打开时确定消息,安排本地通知并将消息存储在 UserDefaults 或其他内容中。没有必要让函数在给定时间运行。
  • @EmilioPelaez 您如何建议仅在发送通知后才使用该 UserDefaults 值?否则,如果他们在发送通知之前再次打开应用程序,我将在应用程序发送之前在应用程序中显示存储的消息。

标签: ios swift unusernotificationcenter


【解决方案1】:

如果您想在特定时间运行代码,那么您应该使用 Timer 类。它非常适合在特定时间间隔重复执行代码,但它也适合在您指定的确切时间运行代码。

这是使用 Timer 构造函数来完成的,该构造函数接受一个 Date 来表示计时器应该触发的时间。您可以随心所欲地设定这个日期,这就是这种方法如此灵活的原因。

作为一个简单的例子,这将创建一个在五秒内调用 runCode() 方法的计时器:

let date = Date().addingTimeInterval(5)

let timer = Timer(fireAt: date, interval: 0, target: self, selector: #selector(runCode), userInfo: nil, repeats: false)

RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)

【讨论】:

  • 这是正确的,也是这样做的一种方式。但是,如果应用程序被挂起(后台),计时器将失效。此外,从某种意义上说,您的控制权有限,您无法收到通知,而是必须事先指定时间。在我自己的许多个人案例中,您并不总是知道需要调用该函数的确切时间。
  • 是的,我也从这里读到过 hackingwithswift.com/example-code/system/… 但是,如果应用程序关闭,这将不起作用。更新了问题并提供了更多详细信息。
【解决方案2】:

你需要做一个事情的清单,这取决于你想让函数做什么。原因是当应用程序在后台运行时,所有进程最初都被暂停,直到应用程序再次进入前台。您可以让应用程序在后台运行,但它们必须遵循苹果规则(如果您不这样做,那么应用程序商店将不会接受您的应用程序)。例如,您可以在应用程序处于后台时播放音频。 See this tutorial for an example. 制作好应用程序使其在后台运行后,您将需要在特定时间调用该函数。使用通知会很好,但实际上这将是您的偏好。至于在您的应用关闭时运行功能,我认为您不应该这样做。

【讨论】:

    【解决方案3】:

    您可以在后台执行模式下触发计时器。

    1) 您需要使用beginBackgroundTaskWithExpirationHandler 选择后台执行。

    2) 在主线程上创建Timer,或者您需要手动将其添加到 mainRunLoop

    RunLoop.main.add(timer, forMode: .defaultRunLoopMode)
    

    注意: 关于后台模式你必须知道的一些事情。

    • 应用程序只需要大约 10 分钟(iOS 7 约为 3 分钟)的后台 执行 - 此后计时器将停止触发。
    • 从 iOS 7 开始,当设备被锁定时,它将暂停前台 应用程序几乎立即。 iOS 7 应用程序启动后计时器不会触发 锁定。

    关闭状态

    在应用不活动时运行计时器是没有意义的。

    【讨论】:

    • 更新了更多细节的问题。
    猜你喜欢
    • 1970-01-01
    • 2015-03-07
    • 1970-01-01
    • 2016-05-27
    • 2017-12-13
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    相关资源
    最近更新 更多