LoginSignup
0
0

More than 5 years have passed since last update.

iOS12 betaでダウンロード再開処理の検証

Posted at

Xcode 10 beta 6のiOS12シミュレータで検証しました。

ダウンロードを再開するためのplistの内容

下記のコードはAlamofireでファイルをダウンロードするリクエストです。
request.cancel()を呼ぶとエラーを返します。そのエラーの中にダウンロードを再開するためのplistが含まれています。

let request = self.manager
        .download(String(format : DownloadService.requestFormat, url, id), to: destination)
        .downloadProgress(closure: {[weak self] progress  in
            guard let wself = self else {
                return
            }

            if let progressClosure = wself.progressClosure {
                progressClosure(id, progress.fractionCompleted)
            }
        })
        .response(completionHandler: {[weak self] response in
            guard let wself = self else {
                return
            }

            guard let error = response.error else {
                if let completedClosure = wself.completedClosure {
                    let cacheURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
                    let fileUrl = cacheURL.appendingPathComponent(String(format : DownloadService.resumeFileFormat, id))
                    if FileManager.default.fileExists(atPath: fileUrl.path) {
                        do {
                            try FileManager.default.removeItem(at: fileUrl)
                        } catch {
                            print("file delete error")
                        }
                    }

                    completedClosure(id)
                }
                return
            }

            //キャンセルの場合もエラーが返ってくる
            guard let resumeData = response.resumeData else {
                if let errorClosure = wself.errorClosure {
                    errorClosure(error)
                }
                return
            }

            do {
                //plistを保存する
                let cacheURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
                let fileUrl = cacheURL.appendingPathComponent(String(format : DownloadService.resumeFileFormat, id))
                try resumeData.write(to: fileUrl)

                if let pauseClosure = wself.pauseClosure {
                    pauseClosure(id)
                }
            } catch {
                print("plist write error")
                return
            }

            return
        })

今回調査したところ、下図のようにiOS11とiOS12でplistの内容が変更されていました。
スクリーンショット 2018-08-19 18.41.47.png

以前まではplistを保存する方法としてPropertyListSerialization propertyList(from:options:format:)でNSDictionaryに変換してからwrite(to:atomically:)で保存していました。

//plistを保存する
let plist = try PropertyListSerialization.propertyList(from: resumeData, options: [.mutableContainersAndLeaves], format: nil)
let cacheURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
let fileUrl = cacheURL.appendingPathComponent(String(format : DownloadService.resumeFileFormat, id))
if !(plist as! NSDictionary).write(to: fileUrl, atomically: true) {
    print("plist write error")
    return
}

iOS12では保存できなくなっていたので、Data write(to:options:)で保存するように変更しました。

バグ

ダウンロード中にアプリを閉じて、再起動すると未完了のURLSessionTaskがSessionManager.sessionの中に残っています。キャンセルしたときと同様にURLSessionTask.errorの中にplistがあります。このplistを使うことでアプリを再起動してもダウンロードを継続することができます。
このplistでダウンロードを再開してから、もう1回アプリの再起動を行うとURLSessionTaskのoriginalRequestが消失します...。

iOS12の検証に使ったプロジェクト

github

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0