Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift-在后台运行iphone应用程序计时器的最佳方式_Ios_Swift - Fatal编程技术网

Ios Swift-在后台运行iphone应用程序计时器的最佳方式

Ios Swift-在后台运行iphone应用程序计时器的最佳方式,ios,swift,Ios,Swift,我对iOS开发一无所知,正在开发一款iPhone烹饪应用程序,让用户可以选择三个“定时器”选项。第一个计时器运行6分钟,第二个计时器运行8.5分钟,最后一个计时器运行11分钟 计时器完成倒计时后,将播放音频文件并在应用程序屏幕中显示消息。除了在测试中发现,当用户转到另一个应用程序(例如,检查电子邮件、使用Safari等)时,计时器停止运行之外,其他一切都可以正常工作。显然,这违背了应用程序的目的,因为用户需要知道计时器何时完成,以便他们可以执行下一步(例如,从炉子上取下一个平底锅) 我已经研究过

我对iOS开发一无所知,正在开发一款iPhone烹饪应用程序,让用户可以选择三个“定时器”选项。第一个计时器运行6分钟,第二个计时器运行8.5分钟,最后一个计时器运行11分钟

计时器完成倒计时后,将播放音频文件并在应用程序屏幕中显示消息。除了在测试中发现,当用户转到另一个应用程序(例如,检查电子邮件、使用Safari等)时,计时器停止运行之外,其他一切都可以正常工作。显然,这违背了应用程序的目的,因为用户需要知道计时器何时完成,以便他们可以执行下一步(例如,从炉子上取下一个平底锅)

我已经研究过背景模式,现在感到困惑。看起来我没有理由(根据苹果的说法)在后台运行这个应用程序(也就是说,它不播放音乐,不使用位置服务等等)。我还不断读到,在后台跑步有10分钟的限制,否则

我也想到了本地和远程通知,但是我提到的页面在苹果的开发者网站上已经不存在了。我现在不知所措,不知所措

有没有办法让这个应用程序在后台运行11分钟?如果是,怎么做


这里有一个更新。我一直在努力了解本地通知和后台任务

本地通知 这显示了一些希望,但我不确定如何在我的场景中实现这一点?如何确保在通知出现/播放声音之前经过适当的时间

例如,用户在中午12:00:00点选择“煮鸡蛋”按钮,应用程序启动计数器6分钟。下午12:01:20,用户阅读一封电子邮件,在12:01:50放下手机阅读报纸之前需要30秒。让我们假设在12:02:50手机进入锁定模式,我如何确保本地通知在3分钟和10秒后触发,以弥补整个6分钟,并播放声音文件,通知用户他们的鸡蛋准备好了

背景任务 如果我可以启动并重新启动后台任务,让计时器在播放声音之前完成,这可能适用于我的场景

下面是我的代码片段(与上面的鸡蛋示例相关),我希望这有助于将我的应用程序置于上下文中:

@IBAction internal func ButtonSoft(sender: UIButton) {

    counter = 360
    TimerDisplay.text = String("06:00")

    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateCounter"), userInfo: "Eggs done!!", repeats: true)


    ButtonSoft.alpha = 0.5
    ButtonMedium.alpha = 0.5
    ButtonHard.alpha = 0.5
    ButtonSoft.enabled = false
    ButtonMedium.enabled = false
    ButtonHard.enabled = false


}




@IBAction internal func ButtonMedium(sender: UIButton) {

    counter = 510
    TimerDisplay.text = String("08:30")

    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateCounter"), userInfo: "Eggs done!!", repeats: true)


    ButtonSoft.alpha = 0.5
    ButtonMedium.alpha = 0.5
    ButtonHard.alpha = 0.5
    ButtonSoft.enabled = false
    ButtonMedium.enabled = false
    ButtonHard.enabled = false


}

@IBAction internal func ButtonHard(sender: UIButton) {

    counter = 660
    TimerDisplay.text = String("11:00")

    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateCounter"), userInfo: "Eggs done!!", repeats: true)


    ButtonSoft.alpha = 0.5
    ButtonMedium.alpha = 0.5
    ButtonHard.alpha = 0.5
    ButtonSoft.enabled = false
    ButtonMedium.enabled = false
    ButtonHard.enabled = false


}


func stopTimer() {

    if counter == 0 {
        timer.invalidate()

    }
}


func updateCounter() {
    counter--


    let seconds = counter % 60
    let minutes = (counter / 60) % 60
    let strMinutes = minutes > 9 ? String(minutes) : "0" + String(minutes)
    let strSeconds = seconds > 9 ? String(seconds) : "0" + String(seconds)
    if seconds > 0 {
        TimerDisplay.text = "\(strMinutes):\(strSeconds)"
    }

    else {
        stopTimer()
        TimerDisplay.text = String("Eggs done!!")
        SoundPlayer.play()
    }

}

@IBAction func ButtonReset(sender: AnyObject) {
    timer.invalidate()
    stopTimer()
    TimerDisplay.text = String("Choose your eggs:")

    ButtonSoft.alpha = 1.0
    ButtonMedium.alpha = 1.0
    ButtonHard.alpha = 1.0
    ButtonSoft.enabled = true
    ButtonMedium.enabled = true
    ButtonHard.enabled = true

}
在运行后台任务方面,我遇到了以下代码示例

要创建后台任务,请执行以下操作:

func someBackgroundTask(timer:NSTimer) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { () -> Void in
        println("do some background task")

        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            println("update some UI")

        })
    })
}
下面的代码行(我认为)使用计时器来运行上述功能:

var timer = NSTimer(timeInterval: 1.0, target: self, selector: "someBackgroundTask:", userInfo: nil, repeats: true)
和下面的代码来停止这一切:

timer.invalidate()
那么,我将如何使其适应我的场景?如果这不可能,我将如何在我的应用程序中使用本地通知


或者我只是放弃iPhone版本的应用程序(我的Apple Watch版本似乎很好用)。

总之,不。你可以询问背景时间,但最新版本的iOS会给你3分钟

如果你是后台声音播放应用程序或导航应用程序,你可以在后台运行更长时间,但你必须申请这些权限,应用程序审查委员会将进行检查

底线是,第三方不能真的做一个计时器应用程序,倒计时任意时间超过3分钟


您可能希望使用定时本地通知。你可以让它们在响的时候发出声音。在2020年8月编辑的
UILocalNotification
上搜索Xcode文档:我不再推荐这种方法


我通过启动一个后台任务,然后设置一个不到一分钟的计时器,取得了一些成功。当计时器启动时,我启动一个新的后台任务并结束旧的后台任务。我只是不断地滚动后台任务,每分钟创建一个新的任务。

我会检查一下(听起来这可能是我在苹果开发网站上找不到的本地通知)。我忘了在帖子中提到,如果iPhone进入锁屏,计时器也会停止(即使应用程序在前台)。您的建议在这种情况下也有效吗?另外,只是大声地想3分钟的限制,但是你能多次要求吗?例如,如果计时器应运行8.5分钟,请将按钮设置为实际运行3分钟计时器,然后再运行3分钟,然后再运行1.5分钟(每次要求3分钟的后台时间)?即使应用程序终止,本地通知也会起作用。我唯一知道本地通知无法发送的时间是在手机关机的情况下。(很明显,如果用户将手机静音,声音就不会播放。)硬币掉了。我以前对本地通知的看法是错误的,现在我意识到我需要重新思考我的应用程序的工作方式,这样就没有计时器,只有在适当的时间触发的本地通知。关于如何实现这一点,你有什么可以参考的吗?我对这一切都不熟悉,不知道从哪里开始。你能更详细地解释一下如何做到这一点吗?大约一年后,当我回顾这一点时,我的建议是对这种行为使用本地通知。如果你真的想采用上述解决方案,请看一看,或者再说一遍,我不再推荐这种方法。这种方法可能有效,但它会很快耗尽用户的电池,还可能导致苹果拒绝你的应用程序。(当你的应用程序运行代码时,它会使CPU保持满功率运行,这是一个巨大的耗电量。苹果公司竭尽全力保护用户的电池寿命,并为此对第三方应用程序施加限制,例如不允许它们在后台运行(或当手机锁定时)无限期。@picciano您能分享代码片段以了解更多信息吗?