swiftui で URLSessionConfiguration.background

iOS

何かのデータをバックグランドでダウンロードしたい時、
URLSession に URLSessionConfiguration.background を指定するのですが、
SwiftUI では困ったことが起こります。

URLSessionConfiguration.background では、
今、何バイトダウンロードしたとか、ダウンロードが完了した時等に受け取れる
delegate を指定する必要があります。

UIViewController のときは、
この delegate に self(UIViewController自身)をセットすれば
よかったのですが、

SwiftUI では従来の UIViewController に View を使うようになっており、
delegate に self(View自身)をセットすることができません。

この問題は、 NSObject, URLSessionDownloadDelegate, ObservableObject を継承した
class を作ることで解消します。

以下に大まかなコードをしめします。
SwiftUI で ObservableObject を使ったことあるなら、わかると思います。

class DownloadManager: NSObject, URLSessionDownloadDelegate, ObservableObject {
    @Published ・・・・

    func startDownload(_ fileName: String) {
        let identifier = "hoge"
        let configuration = URLSessionConfiguration.background(withIdentifier: identifier)
        let session = URLSession(configuration: configuration,
                                 delegate: self,
                                 delegateQueue: nil)

	session.getAllTasks(completionHandler: { (tasks) -> Void in


              ・・・・・・
       }

l      let strDomain = "http://office-aship.info"
                let strUrl = "\(strDomain)/\(fileName)"
                let requestURL = URL(string: strUrl)!

                let urlSessionDownloadTask = session.downloadTask(with: requestURL)
                urlSessionDownloadTask.resume()


        }

        // delegate method はこの辺に記述します
        func urlSession(_ session: URLSession,
                    downloadTask: URLSessionDownloadTask,
                    didWriteData bytesWritten: Int64,
                    totalBytesWritten: Int64,
                    totalBytesExpectedToWrite: Int64) {
        }
}

viewからは以下のように呼び出します。

struct NewsLetterView: View {
    @ObservedObject var observedObjectDownloadManager = DownloadManager()


   // どこかの action 内部等で、、、
    {
        let filePath = "hoge/aaa.jpg"

        // 以下でダウンロード開始
        self.observedObjectDownloadManager
            .startDownload(filePath)
    }

  // ダウンロードの進捗等は ObservedObject の
   // @Published の変数を通して取得する
}
タイトルとURLをコピーしました