我该如何让我的应用在后台持续运行? 我需要越狱我的iPhone才能做到这一点吗?我只需要这个应用程序每隔一段时间检查互联网上的内容并在需要时通知我,仅供个人使用。
我该如何让我的应用在后台持续运行? 我需要越狱我的iPhone才能做到这一点吗?我只需要这个应用程序每隔一段时间检查互联网上的内容并在需要时通知我,仅供个人使用。
不需要越狱。请查看Apple文档中的“执行长时间后台任务”部分。
来自苹果文档: 声明应用支持的后台任务
某些类型的后台执行必须由使用它们的应用事先声明支持。应用程序使用其 Info.plist 文件声明对服务的支持。将 UIBackgroundModes 键添加到 Info.plist 文件中,并将其值设置为包含以下一个或多个字符串的数组:(详见上述链接中的Apple文档。)
我找到了一种方法,通过播放静音来使应用程序在后台运行。
请确保在后台模式中选择了音频播放。
此外,请不要长时间使用此方法,因为它会消耗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。
stop()
,它才会播放静音。 - Dmytro Rostopira我知道这不是你问题的答案,但我认为它是一个解决方案。
假设你想要定期检查某些数据或从互联网获取数据?
创建一个服务,每隔一段时间检查互联网上你想要了解的内容,并创建推送通知,如果服务器宕机,或者你正在监视的内容发生了变化,则会提醒你。仅仅是一个想法。
是的,您可以这样做。为此,您需要在info.plist中设置条目,告诉操作系统我的应用程序将在后台运行。当我想在特定时间戳之后将用户位置传递给服务器时,我已经完成了这项工作。为此,我将“所需后台模式”设置为“应用程序注册位置更新”。
您可以编写类型为UIBackgroundTaskIdentifier的处理程序。
你已经可以在applicationDidEnterBackground方法中实现这个功能了