简体   繁体   English

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

[英]iOS: Keep application running in background

How do I keep my application running in the background? 如何让我的应用程序在后台运行? Would I have to jailbreak my iPhone to do this? 我是否必须越狱我的iPhone才能做到这一点? I just need this app to check something from the internet every set interval and notify when needed, for my own use. 我只需要这个应用程序每隔一定时间间隔从互联网上检查一下,并在需要时通知我自己使用。

Yes, no need to jailbreak. 是的,不需要越狱。 Check out the "Implementing long-running background tasks" section of this doc from Apple . 查看Apple提供的本文档的“实现长时间运行的后台任务”部分。

From Apple's doc: Declaring Your App's Supported Background Tasks 来自Apple的文档:声明应用程序支持的后台任务

Support for some types of background execution must be declared in advance by the app that uses them. 必须由使用它们的应用程序事先声明对某些类型的后台执行的支持。 An app declares support for a service using its Info.plist file. 应用程序使用其Info.plist文件声明对服务的支持。 Add the UIBackgroundModes key to your Info.plist file and set its value to an array containing one or more of the following strings: (see Apple's doc from link mentioned above.) 将UIBackgroundModes键添加到Info.plist文件中,并将其值设置为包含以下一个或多个字符串的数组:(请参阅上面提到的链接中的Apple文档。)

Use local notifications to do that. 使用本地通知执行此操作。 But this will not check every time. 但这不会每次检查。 You will have to set a time where you will check your specific event, you may shorten this by decreasing your time slot. 您必须设置检查特定事件的时间,您可以通过缩短时间来缩短时间。 Read more about local notification to know how to achieve this at: 阅读更多有关本地通知的信息,了解如何实现此目的:

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

I guess this is what you required 我想这就是你所需要的

When an iOS application goes to the background, are lengthy tasks paused? 当iOS应用程序进入后台时,是否会暂停冗长的任务?

iOS Application Background Downloading iOS应用程序背景下载

This might help you ... 这可能对你有所帮助......

Enjoy Coding :) 享受编码:)

I know this is not the answer to your question, but I think it is a solution. 我知道这不是你问题的答案,但我认为这是一个解决方案。

This assumes that your trying to check something or get data from the internet on a regular basis? 这假设您尝试检查某些内容或定期从互联网上获取数据?

Create a service that checks the internet every set interval for whatever it is you want to know, and create a push notification to alert you of it, if the server is down, or whatever it is your trying to monitor has changed state. 创建一个服务,在每个设置的时间间隔内检查互联网,了解您想知道的内容,并创建推送通知以提醒您,服务器是否已关闭,或者您尝试监控的状态是否已更改状态。 Just an idea. 只是一个想法。

I found a way, to keep app running in background by playing silence 我找到了一种方法,通过播放沉默让应用程序在后台运行

Make sure, that you selected audio playback in background modes 确保您在后台模式中选择了音频播放

Also, don't use this method for long time, since it consumes CPU resources and battery juice, but I think it's a suitable way to keep app alive for a few minutes. 此外,不要长时间使用此方法,因为它消耗CPU资源和电池电量,但我认为这是一种让应用程序保持活动几分钟的合适方法。

Just create an instance of SilencePlayer , call play() and then stop() , when you done 只需创建一个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)
    }
}

Tested on iOS 10 and Swift 4 在iOS 10和Swift 4上测试过

Yes you can do something like this. 是的你可以做这样的事情。 For that you need to set entry in info.plist to tell os that my app will run in background. 为此你需要在info.plist中设置条目告诉os我的应用程序将在后台运行。 I have done this while I wanted to pass user's location after particular time stamp to server. 我已经这样做了,而我想在特定时间戳后将用户的位置传递给服务器。 For that I have set "Required background modes" set to "App registers for location updates". 为此,我将“必需的后台模式”设置为“应用寄存器以进行位置更新”。

You can write a handler of type UIBackgroundTaskIdentifier. 您可以编写UIBackgroundTaskIdentifier类型的处理程序。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM