新しいアプリ内でAlamofireを使用しています(Alamofireに基づくダウンロードマネージャーサンプル)バックグラウンドセッションを使用したファイルのダウンロードについて、いくつかの明確化が必要です。 SessionDelegateをオーバーライドして機能させる必要がありますか?それともbackgroundCompletionHandler
?
通常、Alamofireを使用してバックグラウンドでダウンロードを処理する手順は何ですか?また、ダウンロードが流動的で、アプリがリローチしている場合にどのように対処できますか。
このすばらしいチュートリアル に基づいて、 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
}
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
}
}
私は解決策をかなり長く探していました。上記の記事を読むまで。私にとっての問題は、-外部アクセサリ通信を有効にする必要がありました
他のすべては上記のように行われました。 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 ...