使用NSURLSessionDownloadTask进行断点下载

简介:

效果图

downloadImage

下面是完整的下载代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//
// NSURLSessionDownloadViewController.swift
// NSURLSessionDemo
//
// Created by Benjamin on 11/21/15.
// Copyright © 2015 Benjamin. All rights reserved.
//

import UIKit

class NSURLSessionDownloadViewController: UIViewController,NSURLSessionDownloadDelegate {
@IBOutlet weak var progressBar: UIProgressView!
@IBOutlet weak var image: UIImageView!
let imageStringURL = "http://carolinehjq.com/images/avatar.jpg"
var task: NSURLSessionDownloadTask? = nil
var partialData: NSData? = nil
let fileManager = NSFileManager.defaultManager()
var session: NSURLSession!
var request: NSURLRequest!

override func viewDidLoad() {
super.viewDidLoad()
self.session = getSession()
self.request = getRequest(imageStringURL)
self.progressBar.progress = 0
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

//取得单个session
func getSession() -> NSURLSession {
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: self, delegateQueue: nil)
return session
}

/**
return a request by url of image

- parameter imageStringURL: imageStringURL

- returns: NSURLRequest
*/

func getRequest(imageStringURL: String) -> NSURLRequest {
let url = NSURL(string: imageStringURL)
return NSURLRequest(URL: url!)
}

// Start Action
@IBAction func start(sender: UIButton) {
self.task = self.session.downloadTaskWithRequest(self.request)
self.task?.resume()
}

// Pause Action
@IBAction func pause(sender: UIButton) {
print("pause download task")
if self.task != nil {
//取消下载任务,把下载好的数据存起来
self.task?.cancelByProducingResumeData({ (resumeData: NSData?) -> Void in
self.partialData = resumeData
self.task = nil
})
}
}

// Resume Action
@IBAction func resume(sender: UIButton) {
print("resume download task")
if self.task == nil {
if self.partialData != nil {
self.task = self.session.downloadTaskWithResumeData(self.partialData!)
} else {
self.task = self.session.downloadTaskWithRequest(self.request)
}
}
self.task?.resume()
}

/**
创建文件本地保存目录

- parameter location: download location url

- returns: NSURL
*/

func createDirectoryForDownloadItemFromURL(location: NSURL!) -> NSURL{
let documentURL: NSURL = (fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask))[0]
return documentURL.URLByAppendingPathComponent(location.lastPathComponent!)
}

/**
把文件拷贝到指定路径

- parameter location: original location
- parameter destination: destinate location

- returns: success is true, else false
*/

func copyTempFileAtURL(fromLocation location: NSURL, toDestination destination: NSURL) -> Bool {
do {
try fileManager.copyItemAtURL(location, toURL: destination)
} catch {
print("file copy error")
return false
}
return true
}

//MARK:下载完成调用
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
//下载完成后,文件是放在一个临时目录,需要开发者自己拷到防止该文件的目录
let destination = createDirectoryForDownloadItemFromURL(location)
print("download success for url: \(destination)")
//如果文件copy成功
if copyTempFileAtURL(fromLocation: location, toDestination: destination) {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let image1 = UIImage(contentsOfFile: destination.path!)
self.image.image = image1
self.image.contentMode = .ScaleAspectFill
self.image.hidden = false
})
} else {
print("copy file error")
}
self.task = nil
}

//MARK:下载中调用
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
let currentProgress = Double(totalBytesWritten) / Double(totalBytesExpectedToWrite)
print("下载了\(currentProgress)")
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.progressBar.progress = Float(currentProgress)
self.progressBar.hidden = false
}
}

//MARK:继续下载调用
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) {
print("resume...")
}

}

今天学到了Alamofire才有了更简单地方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Alamofire.download(.GET, "https://httpbin.org/stream/100", destination: destination)
.progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
print(totalBytesRead)

// This closure is NOT called on the main queue for performance
// reasons. To update your ui, dispatch to the main queue.
dispatch_async(dispatch_get_main_queue()) {
print("Total bytes read on main queue: \(totalBytesRead)")
}
}
.response { _, _, _, error in
if let error = error {
print("Failed with error: \(error)")
} else {
print("Downloaded file successfully")
}
}
目录
相关文章
|
5月前
|
IDE C# 开发工具
C# | 多线程批量下载文件(创建N个线程同时批量下载文件,只需要几行代码而已)
批量下载文件时使用多线程可以有效缩短完成时间,本文将讲解如何使用C#+CodePlus扩展库快速完成多线程的文件下载。 大部分代码由IDE自动生成,需要我们自己编写的代码正好**10行**。也就是说,只需要10分钟,就可以手撸一个多线程的批量下载器。
95 0
C# | 多线程批量下载文件(创建N个线程同时批量下载文件,只需要几行代码而已)
|
7月前
下载文件 | 下载流文件的处理方式
当下载文件时,返回为流的形式,所以在请求的时候设置 responseType:’arraybuffer’ 或者设置为 responseType: ‘blob’ 的时候,只有当接口返回正确的时候才会下载文件,返回错误的时候,应该是提示用户出错了,但是使用 arraybuffer 或者 blob 的时候,错误的信息也是返回这个形式的。所以需要转换一下。
|
缓存 Java
sevlet实现下载文件功能
希望做一个小板块,实现文件的上传和下载,那么上传实现了,就需要实现下载,阅读了各位的博客总结了一下。在网页中通过超链接是可以访问我的资源的,浏览器不可访问的资源他就会下载到本地,像一些浏览器可以直接访问的如图片,txt文件浏览器会直接打开。这就需要我们在sevlet中统一处理文件下载。
109 0
sevlet实现下载文件功能
|
缓存
上传文件与下载文件不一致的怪事
上传文件与下载文件不一致的怪事
349 0
|
缓存 C# 图形学
C#多线程下载、断点续传的实现
做Unity热更功能的时候,发现单线程下载大尺寸资源文件的效率太低,专门去研究了下多线程下载,这里记录下相关知识点。
|
Android开发 数据格式 XML
okhttp3下载文件检测进度与断点续传
之前有用过retrofit来做下载的功能,虽然retrofit基于okhttp,但是这还是有点不同。 我是在做更新功能的时候用到这个,具体的操作可能不会说太多,因为网上能找到很多基本的操作,我就说下一些流程和BUG,不管是okhttp还是retrofit都适用。
2196 0
|
Web App开发 XML JavaScript
|
前端开发 JavaScript PHP