2014-11-25 61 views
0

我正在爲iPhone開發下載管理器應用程序。我正在使用這個類下載操作:在Swift中完成下載後設置文件名

import UIKit 
import Foundation 

typealias CompleteHandlerBlock =() ->() 

class newDownloadObject: NSObject,NSURLSessionDelegate, NSURLSessionDownloadDelegate { 
    var session: NSURLSession! 
    var handlerQueue: [String : CompleteHandlerBlock]! 

    class var sharedInstance: newDownloadObject { 
     struct Static { 
      static var instance : newDownloadObject? 
      static var token : dispatch_once_t = 0 
     } 

     dispatch_once(&Static.token) { 
      Static.instance = newDownloadObject() 
      Static.instance!.handlerQueue = [String : CompleteHandlerBlock]() 
     } 

     return Static.instance! 
    } 

    //MARK: session delegate 
    func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) { 
     println("session error: \(error?.localizedDescription).") 
    } 

    func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) { 
     completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)) 
    } 

    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {   
     println("session \(session) has finished the download task \(downloadTask) of URL \(location).") 
    } 

    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { 
     println("session \(session) download task \(downloadTask) wrote an additional \(bytesWritten) bytes (total \(totalBytesWritten) bytes) out of an expected \(totalBytesExpectedToWrite) bytes.") 

    } 

    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) { 
     println("session \(session) download task \(downloadTask) resumed at offset \(fileOffset) bytes out of an expected \(expectedTotalBytes) bytes.") 
    } 

    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) { 
     if error == nil { 
      println("session \(session) download completed") 
     } else { 
      println("session \(session) download failed with error \(error?.localizedDescription)") 
     } 
    } 
    func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession) { 
     println("background session \(session) finished events.") 
     if !session.configuration.identifier.isEmpty { 
      callCompletionHandlerForSession(session.configuration.identifier) 
     } 
    } 

    //MARK: completion handler 
    func addCompletionHandler(handler: CompleteHandlerBlock, identifier: String) { 
     handlerQueue[identifier] = handler 
    } 

    func callCompletionHandlerForSession(identifier: String!) { 
     if(identifier == nil){ 
      return 
     } 
     var handler : CompleteHandlerBlock = handlerQueue[identifier]! 
     handlerQueue!.removeValueForKey(identifier) 
     handler() 
    } 
} 

這很好,但我想訪問從iTunes下載的文件。因此此文件必須位於Documents目錄中。

我嘗試在完成下載操作(didFinishDownloadingToURL方法)後將此文件移動到Document目錄。但是我在這裏遇到問題。問題是文件名。它就像
「CFNetworkDownload_qsmwsB.tmp」,並且在下載完成的文件後,它不會改變爲原始名稱(文件名必須是「myBook.pdf」),因此我在iTunes中看到「.tmp」文件。

如何將文件直接下載到Documents目錄或完成下載後如何更改文件名?

回答

3

我在你要找的地方是downloadTask.originalRequest.URL.lastPathComponent它給你的URL中提供的原始文件名。

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) { 
    println("session \(session) has finished the download task \(downloadTask) of URL \(location).") 



    var error : NSError? 
    var fileManager = NSFileManager() 

    // this can be a class variable 
    var docDirectoryURL = NSURL(fileURLWithPath: "/someDirectory/") 

    // Get the original file name from the original request. 
    var destinationFilename = downloadTask.originalRequest.URL.lastPathComponent 
    // append that to your base directory 
    var destinationURL = docDirectoryURL?.URLByAppendingPathComponent(destinationFilename) 

    /* check if the file exists, if so remove it. */ 
    if let path = destinationURL?.path { 
     if fileManager.fileExistsAtPath(path) { 
      fileManager.removeItemAtURL(destinationURL!, error: nil); 
     } 
    } 
    /*copy from the temp location to the final location*/ 
    var success = fileManager.copyItemAtURL(location, toURL: destinationURL!, error: &error) 

    if (!success) { 
     if let actualError = error { 
      println("An Error Occurred: \(actualError)") 
     } 

    } 

} 
+0

謝謝,我有類似的代碼。但是文件的名稱並不是恆定的。我如何從nsurlSession的方法獲取文件名。 – Antiokhos 2014-11-25 17:39:50

+0

我的意思是我發送這個包含下載鏈接的類字符串數組。它爲每個鏈接創建線程並開始下載。在完成downloding後,它給出CFNetworkDownload_randomSomething.tmp作爲名稱。 – Antiokhos 2014-11-25 17:42:03