iOS:让应用程序在后台运行

问题描述 投票:20回答:7

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

iphone objective-c ios xcode4.3 background-process
7个回答
19
投票

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

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

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


5
投票

我想这就是你所需要的

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

iOS Application Background Downloading

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

享受编码:)


5
投票

使用本地通知执行此操作。但这不会每次检查。您必须设置检查特定事件的时间,您可以通过缩短时间来缩短时间。阅读更多有关本地通知的信息,了解如何实现此目的:

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


3
投票

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

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

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


3
投票

我找到了一种方法,通过播放沉默让应用程序在后台运行

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

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


1
投票

是的你可以做这样的事情。为此你需要在info.plist中设置条目告诉os我的应用程序将在后台运行。我已经这样做了,而我想在特定时间戳后将用户的位置传递给服务器。为此,我将“必需的后台模式”设置为“应用寄存器以进行位置更新”。

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


-2
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.