web-dev-qa-db-ja.com

iOS:アプリケーションをバックグラウンドで実行し続ける

アプリケーションをバックグラウンドで実行し続けるにはどうすればよいですか?これを行うには、iPhoneを脱獄する必要がありますか?私は自分の使用のために、設定された間隔ごとにインターネットから何かをチェックし、必要なときに通知するためにこのアプリが必要です。

21
Dennis

はい、脱獄する必要はありません。このドキュメントの「長時間実行されるバックグラウンドタスクの実装」セクションを Apple から確認してください。

Appleのドキュメントから:アプリでサポートされているバックグラウンドタスクを宣言する

一部のタイプのバックグラウンド実行のサポートは、それらを使用するアプリによって事前に宣言する必要があります。アプリは、Info.plistファイルを使用してサービスのサポートを宣言します。 UIBackgroundModesキーをInfo.plistファイルに追加し、その値を次の文字列を1つ以上含む配列に設定します(上記のリンクからAppleのドキュメントを参照してください)。

19
user523234

それにはローカル通知を使用します。しかし、これは毎回チェックするわけではありません。特定のイベントを確認する時間を設定する必要があります。時間枠を短くすることで、これを短縮できます。ローカル通知についての詳細を読んで、これを実現する方法を確認してください。

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

5
Saad

これがあなたが必要なものだと思う

iOSアプリケーションがバックグラウンドになった場合、長時間のタスクは一時停止しますか?

iOSアプリケーションバックグラウンドダウンロード

これはあなたを助けるかもしれません...

コーディングをお楽しみください:)

5
Mrunal

沈黙を再生してアプリをバックグラウンドで実行し続ける方法を見つけました

バックグラウンドモードでオーディオ再生を選択したことを確認してください

また、この方法は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でテスト済み

3
Dima Rostopira

これはあなたの質問に対する答えではないことは知っていますが、解決策だと思います。

これは、定期的に何かをチェックしたり、インターネットからデータを取得しようとしていることを前提としていますか?

知りたいことを設定された間隔ごとにインターネットをチェックするサービスを作成し、プッシュ通知を作成して、サーバーがダウンしている場合、または監視しようとしているものが状態を変更した場合に通知します。ただのアイデア。

3
nycynik

はい、このようなことができます。そのためには、info.plistにエントリを設定して、アプリがバックグラウンドで実行されることをOSに伝える必要があります。特定のタイムスタンプの後にユーザーの場所をサーバーに渡したいときに、これを実行しました。そのために、「必要なバックグラウンドモード」を「位置情報更新のためのアプリの登録」に設定しました。

タイプUIBackgroundTaskIdentifierのハンドラーを作成できます。

1
user1988