如何让我的应用程序在后台运行?我是否必须越狱我的 iPhone 才能做到这一点?我只需要这个应用程序每隔设定的时间间隔从互联网上检查一些东西,并在需要时通知我,供我自己使用。
7 回答
是的,不需要越狱。查看Apple文档的“实现长时间运行的后台任务”部分。
来自 Apple 的文档:Declaring Your App's Supported Background Tasks
对某些类型的后台执行的支持必须由使用它们的应用程序提前声明。应用程序使用其 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 上测试
我知道这不是您问题的答案,但我认为这是一个解决方案。
这假设您尝试定期检查某些内容或从 Internet 获取数据?
创建一个服务,在每个设定的时间间隔检查互联网是否有您想知道的任何内容,并创建一个推送通知来提醒您,如果服务器已关闭,或者您尝试监控的任何内容已更改状态。只是一个想法。
是的,你可以做这样的事情。为此,您需要在 info.plist 中设置条目以告诉操作系统我的应用程序将在后台运行。我已经这样做了,因为我想在特定时间戳之后将用户的位置传递给服务器。为此,我将“必需的后台模式”设置为“应用程序注册以进行位置更新”。
您可以编写 UIBackgroundTaskIdentifier 类型的处理程序。
您已经可以在 applicationDidEnterBackground 方法中执行此操作