アプリケーションをバックグラウンドで実行し続けるにはどうすればよいですか?これを行うには、iPhoneを脱獄する必要がありますか?私は自分の使用のために、設定された間隔ごとにインターネットから何かをチェックし、必要なときに通知するためにこのアプリが必要です。
はい、脱獄する必要はありません。このドキュメントの「長時間実行されるバックグラウンドタスクの実装」セクションを Apple から確認してください。
Appleのドキュメントから:アプリでサポートされているバックグラウンドタスクを宣言する
一部のタイプのバックグラウンド実行のサポートは、それらを使用するアプリによって事前に宣言する必要があります。アプリは、Info.plistファイルを使用してサービスのサポートを宣言します。 UIBackgroundModesキーをInfo.plistファイルに追加し、その値を次の文字列を1つ以上含む配列に設定します(上記のリンクから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でテスト済み
これはあなたの質問に対する答えではないことは知っていますが、解決策だと思います。
これは、定期的に何かをチェックしたり、インターネットからデータを取得しようとしていることを前提としていますか?
知りたいことを設定された間隔ごとにインターネットをチェックするサービスを作成し、プッシュ通知を作成して、サーバーがダウンしている場合、または監視しようとしているものが状態を変更した場合に通知します。ただのアイデア。
はい、このようなことができます。そのためには、info.plistにエントリを設定して、アプリがバックグラウンドで実行されることをOSに伝える必要があります。特定のタイムスタンプの後にユーザーの場所をサーバーに渡したいときに、これを実行しました。そのために、「必要なバックグラウンドモード」を「位置情報更新のためのアプリの登録」に設定しました。
タイプUIBackgroundTaskIdentifierのハンドラーを作成できます。