【问题标题】:set the filename after finish download in Swift在 Swift 中完成下载后设置文件名
【发布时间】:2014-11-26 12:54:47
【问题描述】:

我正在尝试为 iPhone 开发下载管理器应用程序。我正在使用这个类进行下载操作:

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 方法)后将此文件移动到文档目录。但是我在这里遇到问题。问题是文件名。就像
“CFNetworkDownload_qsmwsB.tmp”,下载完成的文件后它不会更改为原始名称。(文件名必须是“myBook.pdf”)结果我看到“.tmp”文件iTunes。

如何将文件直接下载到 Documents 目录或下载完成后如何更改文件名?

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    我知道你在哪里寻找的是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)")
            }
    
        }
    
    }
    

    【讨论】:

    • 谢谢,我有类似的代码。但是文件名不是固定的。我如何从 nsurlSession 的方法中获取文件名。
    • 我的意思是我发送这个包含下载链接的类字符串数组。它为每个链接创建线程并开始下载。完成下载后,它会给出 CFNetworkDownload_randomSomething.tmp 作为名称。
    猜你喜欢
    • 2014-08-02
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 2016-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多