iOS:保持应用程序在后台运行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10674004/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS: Keep application running in background
提问by Dennis
How do I keep my application running in the background? Would I have to jailbreak my iPhone to do this? I just need this app to check something from the internet every set interval and notify when needed, for my own use.
如何让我的应用程序在后台运行?我是否必须越狱我的 iPhone 才能做到这一点?我只需要这个应用程序每隔设定的时间间隔从互联网上检查一些东西,并在需要时通知,供我自己使用。
采纳答案by user523234
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 的文档:Declaring Your App's Supported Background Tasks
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. 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.)
对某些类型的后台执行的支持必须由使用它们的应用程序提前声明。应用程序使用其 Info.plist 文件声明对服务的支持。将 UIBackgroundModes 键添加到您的 Info.plist 文件,并将其值设置为包含以下一个或多个字符串的数组:(请参阅上述链接中的 Apple 文档。)
回答by Saad
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:
使用本地通知来做到这一点。但这不会每次都检查。您必须设置一个时间来检查您的特定事件,您可以通过减少时间段来缩短此时间。在以下位置阅读有关本地通知的更多信息以了解如何实现此目的:
回答by Mrunal
I guess this is what you required
我想这就是你所需要的
When an iOS application goes to the background, are lengthy tasks paused?
iOS Application Background Downloading
This might help you ...
这可能会帮助你...
Enjoy Coding :)
享受编码:)
回答by Dima Rostopira
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 上测试
回答by nycynik
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?
这假设您尝试定期检查某些内容或从 Internet 获取数据?
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.
创建一个服务,在每个设定的时间间隔检查互联网,了解您想知道的任何内容,并创建一个推送通知来提醒您,如果服务器已关闭,或者您尝试监控的任何内容已更改状态。只是一个想法。
回答by user1988
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. 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".
是的,你可以做这样的事情。为此,您需要在 info.plist 中设置条目以告诉 os 我的应用程序将在后台运行。我已经这样做了,因为我想在特定时间戳后将用户的位置传递给服务器。为此,我将“必需的后台模式”设置为“应用程序注册位置更新”。
You can write a handler of type UIBackgroundTaskIdentifier.
您可以编写 UIBackgroundTaskIdentifier 类型的处理程序。
回答by user1320885
You can already do this in the applicationDidEnterBackground Method
您已经可以在 applicationDidEnterBackground 方法中执行此操作