Swift 下载文件 支持断点下载

本文介绍如何使用NSURLSessionDownloadTask在Swift中实现文件下载,特别是支持断点续传功能。通过遵循NSURLSessionDownloadDelegate协议,可以实现任务的暂停、取消和恢复,并确保下载在后台线程进行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NSURLConnection完成的三个主要任务:获取数据(通常是JSON、XML等)、文件上传、文件下载。而在NSURLSession时代,他们分别由三个任务来完成:NSURLSessionData、NSURLSessionUploadTask、NSURLSessionDownloadTask,这三个类都是NSURLSessionTask这个抽象类的子类,相比直接使用NSURLConnection,NSURLSessionTask支持任务的暂停、取消和恢复,并且默认任务运行在其他非主线程中

1.定义好变量,并遵循NSURLSessionDownloadDelegate协议

    var downloadTask : NSURLSessionDownloadTask?
    var partialData : NSData?
    var session : NSURLSession?
    var request : NSMutableURLRequest?


2.为每个按钮增加点击事件

    //开始下载
    @IBAction func onDownLoad(sender: AnyObject) {
        self.downloadFile()
    }
    //挂起下载
    @IBAction func onSuspend(sender: AnyObject) {
        if(self.downloadTask != nil)
        {
            //挂起下载任务,将下载好的数据进行保存
            self.downloadTask?.cancelByProducingResumeData({ (resumeData:NSData!) -> Void in
                self.partialData = resumeData
                self.downloadTask = nil
            })
        }
//        downloadTask!.suspend()
    }
    //恢复下载
    @IBAction func onResume(sender: AnyObject) {
        if(self.downloadTask == nil)
        {
            //判断是否又已下载数据,有的话就断点续传,没有就完全重新下载
        if(self.partialData != nil)
        {
            self.downloadTask = self.session?.downloadTaskWithResumeData(self.partialData!)
            }
        else{
            self.downloadTask = self.session?.downloadTaskWithRequest(self.request!)
            }
        }
        downloadTask!.resume()
    }
    //开始下载文件
    func downloadFile()
    {
        NSLog("正在下载")
        //创建URL
        var urlStr:NSString = NSString(string: "http://cdn.wall88.com/51a317b5ef36713194.jpg")
        urlStr = urlStr.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
        var url = NSURL(string: urlStr)!
        //创建请求
        request = NSMutableURLRequest(URL: url)
        //创建默认会话
        var sessionConfig : NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
        sessionConfig.timeoutIntervalForRequest = 20 //设置请求超时时间
        sessionConfig.allowsCellularAccess = true //是否允许蜂窝网络下载
        //创建会话
        session = NSURLSession(configuration: sessionConfig, delegate: self, delegateQueue: nil)//指定配置和代理
        downloadTask = session!.downloadTaskWithRequest(request!)
        downloadTask!.resume()
    }

3.根据下载内容的大小更新进度条

    //设置页面状态
    func setUIStatus(totalBytesWritten : Int64,expectedToWrite totalBytesExpectedToWrite:Int64 )
    {
        //调用主线程刷新UI
        dispatch_async(dispatch_get_main_queue(), {
            if(Int(totalBytesExpectedToWrite) != 0 && Int(totalBytesWritten) != 0)
            {
                //更新进度条
                self.ps.progress = Float(Float(totalBytesWritten) / Float(totalBytesExpectedToWrite))
                if(totalBytesExpectedToWrite == totalBytesWritten)
                {
                    self.lbl_hint.text! = "下载完毕"
                    UIApplication.sharedApplication().networkActivityIndicatorVisible = false
                    self.btn_download.enabled = true
                }
                else{
                    self.lbl_hint.text = "正在下载"
                    UIApplication.sharedApplication().networkActivityIndicatorVisible = true
                }
            }
            }
        )
    }


4.下载

    //任务完成,不管是否下载成功
    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
        self.setUIStatus(0, expectedToWrite: 0)
        if(error != nil)
        {
            NSLog("error is:\(error!.localizedDescription)")
        }
    }
    
    //下载完成
    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
        var error:NSError?
        var cachePath : NSString = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true).first as NSString
        var savePath = cachePath.stringByAppendingPathComponent(lbl_title.text!)
        NSLog("\(savePath)")
        var saveUrl : NSURL = NSURL(fileURLWithPath: savePath)!
        var defalutManager = NSFileManager.defaultManager()
        //判断文件是否存在,存在则删除
        if(defalutManager.fileExistsAtPath(savePath))
        {
            defalutManager.removeItemAtPath(savePath, error: &error)
        }
        //下载成功后,文件是保存在一个临时的目录中的,需要自己拷置到该文件的目录
        defalutManager.copyItemAtURL(location, toURL: saveUrl, error: &error)
        if(error != nil)
        {
        NSLog("\(error)")
        }
    }
    
    //下载中
    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        self.setUIStatus(totalBytesWritten, expectedToWrite: totalBytesExpectedToWrite)
    }







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值