【问题标题】:iOS: Keep application running in backgroundiOS:让应用程序在后台运行
【发布时间】:2012-05-27 06:57:08
【问题描述】:

如何让我的应用程序在后台运行? 我是否必须越狱我的 iPhone 才能做到这一点?我只需要这个应用程序每隔设定的时间间隔从互联网上检查一些东西,并在需要时通知我,供我自己使用。

【问题讨论】:

  • 嗨丹尼斯希望你得到你的答案。如果是,那么您能否将您各自的答案标记为正确和赞成...

标签: iphone objective-c ios xcode4.3 background-process


【解决方案1】:

是的,无需越狱。从Apple 查看本文档的“实现长时间运行的后台任务”部分。

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

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

【讨论】:

  • @takrishna,如果您正在编写此应用程序供自己使用,请设置 UIBackgroundModes 值“voip”(IP 语音)。这是在后台永远保持活力的最简单类型的应用程序。 (但不要将其提交到应用商店,除非它确实是 VOIP 应用。)
  • 对于应用商店应用,如果您没有服务器定期向您的手机发送“远程通知”,那么您唯一的其他选择就是“后台获取”。 stackoverflow.com/a/37311611/199364
【解决方案2】:

我想这就是你需要的

When an iOS application goes to the background, are lengthy tasks paused?

iOS Application Background Downloading

这可能会对你有所帮助...

享受编码:)

【讨论】:

    【解决方案3】:

    使用本地通知来做到这一点。但这不会每次都检查。您必须设置检查特定事件的时间,您可以通过减少时间段来缩短此时间。阅读有关本地通知的更多信息,了解如何实现这一点:

    http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Introduction/Introduction.html

    【讨论】:

    • 不,如果应用程序在后台,本地通知所做的就是向用户显示该通知。除非用户单击通知将应用程序置于前台,否则您无法进行任何实际工作。
    【解决方案4】:

    我找到了一种方法,通过静音保持应用在后台运行

    确保您选择了在后台模式下播放音频

    另外,不要长时间使用这种方法,因为它会消耗 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 上测试

    【讨论】:

    • 感谢您分享这个。
    • :- 静音播放器播放声音的时间是多少?
    • @YogeshRaut 在您致电stop()之前,它会一直保持沉默
    • @DimaRostopira 我正在做类似的事情,但请注意我的应用在几个小时后仍然退出。我的代码确实使用AVAudioPlayermind 而不是像你这样的音频队列,你看到这成功地让你的应用程序运行了多长时间?
    • @simonthumper 我只用了 3 分钟,我不需要更多
    【解决方案5】:

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

    这假设您尝试定期检查某些内容或从 Internet 获取数据?

    创建一个服务,在每个设定的时间间隔检查互联网是否有您想知道的任何内容,并创建一个推送通知以提醒您,如果服务器已关闭,或者您尝试监控的任何内容已更改状态.只是一个想法。

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

        您已经可以在 applicationDidEnterBackground 方法中执行此操作

        【讨论】:

        • 我以为应用会在一段时间后自动终止,不是吗?如果我错了,请原谅我的无知。我对 iOS 编程很陌生。
        • 除非 iOS 需要该内存用于另一个应用程序,否则不会,只要您在后台执行某项操作
        • 没有。应用程序不能在后台运行超过 10 分钟,除了少数特定情况(VOIP、播放音频等)
        • 一个播放音频的 iOS 应用程序将在后台无限期地播放音频,只要音频正在播放。如果应用程序随后停止或暂停音频,它将在 10 分钟后终止。我知道这一点是因为我在应用程序中有一个睡眠定时器。上面的代码似乎有很多行,所以我猜它可以被简化。我在后台播放音频,代码少得多。
        猜你喜欢
        • 1970-01-01
        • 2018-05-28
        • 1970-01-01
        • 2013-02-26
        • 2015-01-04
        • 1970-01-01
        • 2015-04-25
        • 2021-12-22
        相关资源
        最近更新 更多