web-dev-qa-db-ja.com

バックグラウンドセッションでのAlamoFireダウンロード

新しいアプリ内でAlamofireを使用しています(Alamofireに基づくダウンロードマネージャーサンプル)バックグラウンドセッションを使用したファイルのダウンロードについて、いくつかの明確化が必要です。 SessionDelegateをオーバーライドして機能させる必要がありますか?それともbackgroundCompletionHandler

通常、Alamofireを使用してバックグラウンドでダウンロードを処理する手順は何ですか?また、ダウンロードが流動的で、アプリがリローチしている場合にどのように対処できますか。

37
LastMove

更新

このすばらしいチュートリアル に基づいて、 GitHub で利用可能なサンプルプロジェクトをまとめました。バックグラウンドセッション管理の例があります。

Appleの RL Loading System Programming Guide によると:

IOSとOS Xの両方で、ユーザーがアプリを再起動すると、アプリはすぐに、アプリが最後に実行されたときに未処理のタスクがあったセッションと同じ識別子を持つバックグラウンド構成オブジェクトを作成し、それらの構成オブジェクトごとにセッションを作成する必要があります。これらの新しいセッションは、同様に進行中のバックグラウンドアクティビティに自動的に再関連付けされます。

したがって、適切なバックグラウンドセッション構成インスタンスを使用することにより、ダウンロードが「流動的」になることはありません。

また、 この回答 が非常に役立つこともわかっています。

元の答え

Alamofireの GitHubページ から:

アプリケーションは、バックグラウンドおよび一時セッション用のマネージャーを作成でき、デフォルトのヘッダー(HTTPAdditionalHeaders)やタイムアウト間隔(timeoutIntervalForRequest)などのデフォルトのセッション構成をカスタマイズする新しいマネージャーも作成できます。

デフォルトでは、トップレベルのメソッドはデフォルトのセッション構成で共有Managerインスタンスを使用します。ただし、次のようなバックグラウンドセッション構成でマネージャーを作成できます。

let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.example.app.background")
let manager = Alamofire.Manager(configuration: configuration)

その後、このManagerインスタンスを使用してリクエストを作成できます。

manager.startRequestsImmediately = true
let request = NSURLRequest(URL: NSURL(string: "your.url.here")!)
manager.request(request)

実装を見ると、backgroundCompletionHandlerというプロパティもあるため、完了ブロックを追加できます。

manager.backgroundCompletionHandler = {
        // do something when the request has finished
    }
31
József Vesza

Alamofireを使用すると、実際には非常に簡単です。

1)Alamofire.Managerには、バックグラウンドセッション識別子を設定する必要があります。

class NetworkManager {
    ...
    private lazy var backgroundManager: Alamofire.SessionManager = {
        let bundleIdentifier = ...
        return Alamofire.SessionManager(configuration: URLSessionConfiguration.background(withIdentifier: bundleIdentifier + ".background"))
    }()
    ...
}

2)App Delegateでapplication(_:handleEventsForBackgroundURLSession:completionHandler:を実装し、完了ハンドラーをAlamofire.SessionManager.backgroundCompletionHandlerに渡します。

私の場合、アプリのデリゲートメソッドは次のようになります

func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
    NetworkManager.default.backgroundCompletionHandler = completionHandler
}

私のネットワークマネージャーには、マネージャープロパティを設定するための次のような計算プロパティがあります。

var backgroundCompletionHandler: (() -> Void)? {
    get {
        return backgroundManager.backgroundCompletionHandler
    }
    set {
        backgroundManager.backgroundCompletionHandler = newValue
    }
}
25
Luca Torella

私は解決策をかなり長く探していました。上記の記事を読むまで。私にとっての問題は、-外部アクセサリ通信を有効にする必要がありました

enter image description here

他のすべては上記のように行われました。 AppDelegate:

func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
        BackendAPIManager.sharedInstance.backgroundCompletionHandler = completionHandler
    }

シングルトン:

import Alamofire

class BackendAPIManager: NSObject {
    static let sharedInstance = BackendAPIManager()

    var alamoFireManager : Alamofire.SessionManager!

    var backgroundCompletionHandler: (() -> Void)? {
        get {
            return alamoFireManager?.backgroundCompletionHandler
        }
        set {
            alamoFireManager?.backgroundCompletionHandler = newValue
        }
    }

    fileprivate override init()
    {
        let configuration = URLSessionConfiguration.background(withIdentifier: "com.url.background")
        configuration.timeoutIntervalForRequest = 200 // seconds
        configuration.timeoutIntervalForResource = 200
        self.alamoFireManager = Alamofire.SessionManager(configuration: configuration)
    }
}

そして、呼び出しは次の方法で行われます。

BackendAPIManager.sharedInstance.alamoFireManager.upload(multipartFormData: { (multipartFormData) in ...
8
Naloiko Eugene