2015-12-07 6 views
10

私のアプリはかなり大きいファイル(390Mb)をダウンロードしなければなりません。 ダウンロード用にTCBlopDownloadSwiftを使用しています(私はswift 2.0用に変換して正常に動作します)。 アプリが強制的に強制的にダウンロードを再開できるようにしたいと思います。 私は、アプリケーションが終了しても、ダウンロードされたデータを( "com.apple.nsurlsessiond/Downloads /" + bundleIdentifierの)キャッシュにtmpファイルとして見つけることができます。 しかし、私は使用してダウンロードのデータを取得しようとすると:アプリを強制終了するとダウンロードを再開するにはどうすればいいですか?

func dataInCacheForName (name : String) -> NSData? { 
    let PathToCache = (NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory , .UserDomainMask, true)[0] as NSString).stringByAppendingPathComponent("com.apple.nsurlsessiond/Downloads/" + bundleIdentifier) 
    let path = (PathToCache as NSString).stringByAppendingPathComponent(name) 
    let data = NSData(contentsOfFile: path) 
    print("data : \(data?.length)") 
    return data 
} 

それはnilを返しますが、ファイルがnilではありません。私はファイルを移動することができるので、私はドキュメント内のファイルを移動しようとしました。バックグラウンドダウンロードのための

-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL 

-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL 

-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL 

無効なレジュームデータ:私はデータをダウンロードを再開しようとした場合しかし、その後、私はエラーを取得します。バックグラウンドダウンロードはhttpまたはhttpsを使用する必要があり、アクセス可能なファイルにダウンロードする必要があります。

とURLSession

(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?) 

error userInfo : Optional([:]) 

: Optional(Error Domain=NSURLErrorDomain Code=-3003 "(null)") 

にエラーコード-3003が

をファイルに書き込むことは不可能を意味し、私は多くの記事を読んで、まだ答え

最も有望を見つけることができませんはhttps://forums.developer.apple.com/thread/24770

+1

単にNSURLSessionを使用し、バックグラウンドタスクでファイルをダウンロードしてみませんか? – Lefteris

+0

バックグラウンドタスクとしてファイルをダウンロードします。アプリが強制的にダウンロードを再開できるようにしたい場合:ユーザーがアプリを再起動した場合、キャッシュ内に保存されたデータを使用してダウンロードが再開されます。 – kholl

+3

バックグラウンドのNSURLSessionタスクでは、ダウンロードはOSで処理され、アプリでは処理されません。あなたのアプリは終了/クラッシュすることができますが、ダウンロードは停止しません。 – Lefteris

答えて

3

だから、問題はライブラリから来て、私は説明する:

TCBlobDownloadSwiftにはカスタムデリゲートがあり、urlSessionDelegateメソッドの最後に呼び出されます(例:カスタムデリゲートはtotalByteWrittenおよびtotalBytesExpectedToWriteの代わりに進捗値を指定します)。 :

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { 
    guard let download = self.downloads[downloadTask.taskIdentifier] else{ 
     return 
    } 
    let progress = totalBytesExpectedToWrite == NSURLSessionTransferSizeUnknown ? -1 : Float(totalBytesWritten)/Float(totalBytesExpectedToWrite) 
    print("progress : \(progress)") 
    // the delegate is in fact called download and has more parameter . 
    customDelegate(download , progress : progress) 
} 

とうまくいきます。しかし、アプリケーションの再起動時にダウンロードを再開すると、ダウンロードは登録されず、downloadTask.taskIdentifierはnilを返すので、カスタムデリゲートは呼び出されません!!

あなたは、このコード(NSURLSessionDelegate議定書に続くオブジェクトが作成されたときにメソッドが呼び出された)を使用する必要が強制終了した後にダウンロードを再開するためには:

public func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?) { 
    if let error = sessionError { 
    print("error : \(error)") 
    let directory = NSURL(fileURLWithPath: fileManage.Path) 
    if let resumedData = error.userInfo[NSURLSessionDownloadTaskResumeData] as? NSData { 
     let url = error.userInfo[NSURLErrorFailingURLStringErrorKey] as? String 
     // get name from url just read a dictionnary of name and url 
     let name = getNameFromURL(url!) 
     // start the download 
     self.manager.downloadFileWithResumeData(resumedData, toDirectory: directory , withName: name, andDelegate: self) 
     } 
    } 
} 

を私は破壊しなければなりませんでしたカスタムデリゲート(NSURより1異なるとライブラリを使用する場合、ライブラリは

TLDR

を(それの構造は、アプリの力が、終了した場合、ダウンロードを再開することはできません) NSURLSession、タスク:NSURLSessionTask、didCompleteWithError sessionError:?NSError)メソッド

PS:答えてくれてありがとう、私は私のポストでどのように誤解を招く理解LSessionDelegate)問題がURLSession(セッションを呼び出さないカスタムデリゲートから来るかもしれません。

アプリが強制終了した後にダウンロードを再開できるようにするフレームワークで作業するようにしています(実際にはその特定のケースに対してデリゲートメソッドを追加するだけですもっと複雑な場合は、あとで時間がありません)