iOS:保持应用在后台运行

25

我该如何让我的应用在后台持续运行? 我需要越狱我的iPhone才能做到这一点吗?我只需要这个应用程序每隔一段时间检查互联网上的内容并在需要时通知我,仅供个人使用。


嗨,丹尼斯,希望你已经得到了答案。如果是的话,能否请您将相应的答案标记为正确并点赞... - Mrunal
7个回答

21

不需要越狱。请查看Apple文档中的“执行长时间后台任务”部分。

来自苹果文档: 声明应用支持的后台任务

某些类型的后台执行必须由使用它们的应用事先声明支持。应用程序使用其 Info.plist 文件声明对服务的支持。将 UIBackgroundModes 键添加到 Info.plist 文件中,并将其值设置为包含以下一个或多个字符串的数组:(详见上述链接中的Apple文档。)


1
@takrishna,如果您正在为自己编写此应用程序,则将UIBackgroundModes值设置为“voip”(Voice over IP)。这是在后台永久保持活动状态的最简单的应用程序类型。(但是,除非它真的是VOIP应用程序,否则不要提交到应用商店。) - ToolmakerSteve
对于应用商店中的应用,如果您没有服务器定期向手机发送“远程通知”的选项,则唯一的选择是“后台获取”。http://stackoverflow.com/a/37311611/199364 - ToolmakerSteve

5

我找到了一种方法,通过播放静音来使应用程序在后台运行。

请确保在后台模式中选择了音频播放。

此外,请不要长时间使用此方法,因为它会消耗CPU资源和电池电量,但我认为这是使应用程序保持活动状态几分钟的合适方式。

只需创建SilencePlayer实例,调用play(),然后在完成后调用stop()即可。

import CoreAudio

public class SilencePlayer {
    private var audioQueue: AudioQueueRef? = nil
    public private(set) var isStarted = false

    public func play() {
        if isStarted { return }
        print("Playing silence")
        let avs = AVAudioSession.sharedInstance()
        try! avs.setCategory(AVAudioSessionCategoryPlayback, with: .mixWithOthers)
        try! avs.setActive(true)
        isStarted = true
        var streamFormat = AudioStreamBasicDescription(
            mSampleRate: 16000,
            mFormatID: kAudioFormatLinearPCM,
            mFormatFlags: kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked,
            mBytesPerPacket: 2,
            mFramesPerPacket: 1,
            mBytesPerFrame: 2,
            mChannelsPerFrame: 1,
            mBitsPerChannel: 16,
            mReserved: 0
        )
        let status = AudioQueueNewOutput(
            &streamFormat,
            SilenceQueueOutputCallback,
            nil, nil, nil, 0,
            &audioQueue
        )
        print("OSStatus for silence \(status)")
        var buffers = Array<AudioQueueBufferRef?>.init(repeating: nil, count: 3)
        for i in 0..<3 {
            buffers[i]?.pointee.mAudioDataByteSize = 320
            AudioQueueAllocateBuffer(audioQueue!, 320, &(buffers[i]))
            SilenceQueueOutputCallback(nil, audioQueue!, buffers[i]!)
        }
        let startStatus = AudioQueueStart(audioQueue!, nil)
        print("Start status for silence \(startStatus)")
    }

    public func stop() {
        guard isStarted else { return }
        print("Called stop silence")
        if let aq = audioQueue {
            AudioQueueStop(aq, true)
            audioQueue = nil
        }
        try! AVAudioSession.sharedInstance().setActive(false)
        isStarted = false
    }

}

fileprivate func SilenceQueueOutputCallback(_ userData: UnsafeMutableRawPointer?, _ audioQueueRef: AudioQueueRef, _ bufferRef: AudioQueueBufferRef) -> Void {
    let pointer = bufferRef.pointee.mAudioData
    let length = bufferRef.pointee.mAudioDataByteSize
    memset(pointer, 0, Int(length))
    if AudioQueueEnqueueBuffer(audioQueueRef, bufferRef, 0, nil) != 0 {
        AudioQueueFreeBuffer(audioQueueRef, bufferRef)
    }
}

测试过适用于iOS 10和Swift 4。


谢谢你分享这个。 - Yogesh Raut
沉默玩家播放声音需要多长时间? - Yogesh Raut
@YogeshRaut 直到你调用 stop(),它才会播放静音。 - Dmytro Rostopira
1
@simonthumper 我只用了3分钟,我不需要更多的时间。 - Dmytro Rostopira
@DimaRostopira 好的,没问题! :) - simonthumper
显示剩余5条评论

5
我猜这就是你需要的内容。
当iOS应用程序进入后台时,长时间运行的任务会暂停吗? iOS应用程序后台下载 这可能会对你有所帮助...
享受编程 :)

4

2
不,如果应用程序在后台运行,本地通知只会向用户显示该通知。 除非用户点击通知将应用程序带到前台,否则您无法执行任何实际工作。 - ToolmakerSteve

3

我知道这不是你问题的答案,但我认为它是一个解决方案。

假设你想要定期检查某些数据或从互联网获取数据?

创建一个服务,每隔一段时间检查互联网上你想要了解的内容,并创建推送通知,如果服务器宕机,或者你正在监视的内容发生了变化,则会提醒你。仅仅是一个想法。


1

是的,您可以这样做。为此,您需要在info.plist中设置条目,告诉操作系统我的应用程序将在后台运行。当我想在特定时间戳之后将用户位置传递给服务器时,我已经完成了这项工作。为此,我将“所需后台模式”设置为“应用程序注册位置更新”。

您可以编写类型为UIBackgroundTaskIdentifier的处理程序。


-2

你已经可以在applicationDidEnterBackground方法中实现这个功能了


我以为应用程序会在一定时间后自动终止,不是吗?如果我说错了,请原谅我的无知。我是iOS编程的新手。 - Dennis
除非iOS需要该内存用于另一个应用程序,否则它不会被释放,只要您在后台执行某些操作。 - user1320885
5
除了一些特定情况(如VOIP、播放音频等),应用程序不能在后台运行超过10分钟。 - Greg
一款播放音频的iOS应用程序只要音频正在播放,就会在后台无限期地继续播放。如果应用程序停止或暂停音频,则在10分钟后将被终止。我知道这是因为我的一个应用程序中有一个睡眠计时器。上面的代码似乎有很多行,所以我猜它可以简化。我使用更少的代码在后台播放音频。 - SundialSoft

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接