最近在做一个小项目的时候,发现使用NSURLSession或者AFNNetworking进行断点续传时诸多的不便,于是自己封装了一个类来实现断点续传,在程序重新启动时仍然可以继续下载(需自己调用方法),同时可以在同一时间多次调用该类方法。使用时请注意传入各参数的合理性,方法内部并没有对传入的参数进行修正

主要技术: NSURLConnection、block、NFFileHandle

1、首先,我提供一个类方法,供外界调用。 创建的类名为DownloadService

 //
// DownloadService.h
// 11111
//
// Created by Liu Feng on 14-2-17.
// Copyright (c) 2014年 Liu Feng. All rights reserved.
// #import <Foundation/Foundation.h> typedef void (^DownloadServiceSuccess)(NSString *savePath);
typedef void (^DownloadServiceFailure)(NSError *error); @interface DownloadService : NSObject
/**
* 下载指定URL的资源到路径
*
* @param urlStr 网络资源路径
* @param toPath 本地存储文件夹
* @param capacity 缓存大小,单位为Mb
* @param success 成功时回传本地存储路径
* @param failure 失败时回调的错误原因
*/
+ (void)downLoadWithURL:(NSString *)urlStr toDirectory:(NSString *)toDirectory cacheCapacity:(NSUInteger)capacity success:(DownloadServiceSuccess)success failure:(DownloadServiceFailure)failure; @end

2、在.m中实现

 //
// DownloadService.m
// 11111
//
// Created by Liu Feng on 14-2-17.
// Copyright (c) 2014年 Liu Feng. All rights reserved.
// #import "DownloadService.h" static DownloadService *_download;
static NSMutableDictionary *_dictPath;
static NSMutableDictionary *_dictBlock;
static NSMutableDictionary *_dictHandle;
static unsigned long long _cacheCapacity; // 缓存
static NSMutableData *_cacheData; typedef void (^myBlcok)(NSString *savePath, NSError *error); @interface DownloadService ()<NSURLConnectionDataDelegate> @end @implementation DownloadService + (void)initialize
{
_download = [[DownloadService alloc] init];
_dictPath = [NSMutableDictionary dictionary]; // 存储文件路径
_dictBlock = [NSMutableDictionary dictionary]; // 存储block
_dictHandle = [NSMutableDictionary dictionary]; // 存储NSFileHandle对象
_cacheData = [NSMutableData data]; // 存放缓存
} + (void)downLoadWithURL:(NSString *)urlStr toDirectory:(NSString *)toDirectory cacheCapacity:(NSInteger)capacity success:(DownloadServiceSuccess)success failure:(DownloadServiceFailure)failure{ // 1. 创建文件
NSString *fileName = [urlStr lastPathComponent];
NSString *filePath = [NSString stringWithFormat:@"%@/%@", toDirectory, fileName]; // 记录文件起始位置
unsigned long long from = ;
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]){ // 已经存在
from = [[NSData dataWithContentsOfFile:filePath] length];
}else{ // 不存在,直接创建
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
} // url
NSURL *url = [NSURL URLWithString:urlStr]; // 请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0f]; // 设置请求头文件
NSString *rangeValue = [NSString stringWithFormat:@"bytes=%llu-", from];
[request addValue:rangeValue forHTTPHeaderField:@"Range"]; // 创建连接
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:_download]; // 保存文章连接
_dictPath[connection.description] = filePath; // 保存block,用于回调
myBlcok block = ^(NSString *savePath, NSError *error){
if (error) {
if (failure) {
failure(error);
}
}else{
if (success) {
success(savePath);
}
}
};
_dictBlock[connection.description] = block; // 保存缓存大小
_cacheCapacity = capacity * * ; // 开始连接
[connection start];
}
/**
* 接收到服务器响应
*
* @param connection 哪一个连接
* @param response 响应对象
*/
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// 取出文章地址
NSString *filePath = _dictPath[connection.description]; // 打开文件准备输入
NSFileHandle *outFile = [NSFileHandle fileHandleForWritingAtPath:filePath]; // 保存文件操作对象
_dictHandle[connection.description] = outFile;
}
/**
* 开始接收数据
*
* @param connection 哪一个连接
* @param data 二进制数据
*/
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// 取出文件操作对象
NSFileHandle *outFile = _dictHandle[connection.description]; // 移动到文件结尾
[outFile seekToEndOfFile]; // 保存数据
[_cacheData appendData:data]; if (_cacheData.length >= _cacheCapacity) {
// 写入文件
[outFile writeData:data]; // 清空数据
[_cacheData setLength:];
}
}
/**
* 连接出错
*
* @param connection 哪一个连接出错
* @param error 错误信息
*/
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// 取出文件操作对象
NSFileHandle *outFile = _dictHandle[connection.description]; // 关闭文件操作
[outFile closeFile]; // 回调block
myBlcok block = _dictBlock[connection.description]; if (block) {
block(nil, error);
} // 移除字典中
[_dictHandle removeObjectForKey:connection.description];
[_dictPath removeObjectForKey:connection.debugDescription];
[_dictBlock removeObjectForKey:connection.description];
}
/**
* 结束加载
*
* @param connection 哪一个连接
*/
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// 取出文件操作对象
NSFileHandle *outFile = _dictHandle[connection.description]; // 关闭文件操作
[outFile closeFile]; // 取出路径
NSString *savePath = [_dictPath objectForKey:connection.description]; // 取出block
myBlcok block = _dictBlock[connection.description]; // 回调
if (block) {
block(savePath, nil);
} // 移除字典中
[_dictHandle removeObjectForKey:connection.description];
[_dictPath removeObjectForKey:connection.debugDescription];
[_dictBlock removeObjectForKey:connection.description];
} @end

iOS开发网络编程之断点续传-NSURLConnection的更多相关文章

  1. IOS开发——网络编程总汇

    关于IOS的网络编程,大家都会想到C实现的底层BSD ,CFNetwork和NSURL之类的库,虽然如今非常多第三方库非常方便,可是作为一名开发人员,也须要了解底层代码. 以下的思维导图是关于眼下开发 ...

  2. ios开发 网络编程浅析(一)

    iphone包含了很多框架和库,从底层的套接字到不同层次的封装,可以方便地给程序添加网络功能. (1)BSD套接字.最底层的套接字,这是Unix网络开发常用的API.如果从其他系统移植程序,而程序用的 ...

  3. iOS开发——网络编程Swift篇&Alamofire详解

    Alamofire详解 预览图 Swift Alamofire 简介 Alamofire是 Swift 语言的 HTTP 网络开发工具包,相当于Swift实现AFNetworking版本. 当然,AF ...

  4. iOS开发——网络编程OC篇&(一)XMPP简单介绍与准备

    XMPP简单介绍与准备 一.即时通讯简单介绍 1.简单说明 即时通讯技术(IM)支持用户在线实时交谈.如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方都看到交谈 ...

  5. iOS开发——网络编程OC篇&Socket编程

    Socket编程 一.网络各个协议:TCP/IP.SOCKET.HTTP等 网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 其中物理层.数据链路层和网络层通常被称作 ...

  6. iOS开发——网络编程OC篇&使用WebView构建HyBird应用

    使用WebView构建HyBird应用 HyBird是一种本地技术与Web相结合,能过实现跨平台的移动应用开发,最常用的一个框架:PhoneGap 一:首先,写好html代码 <!DOCTYPE ...

  7. iOS开发——网络编程Swift篇&(二)同/异&步请求

    同/异&步请求 同步: // MARK: - 同步请求 func httpSynchronousRequest() { //创建NSURL对象 var url:NSURL! = NSURL(s ...

  8. iOS开发——网络编程Swift篇&(八)SwiftyJSON详解

    SwiftyJSON详解 最近看了一些网络请求的例子,发现Swift在解析JSON数据时特别别扭,总是要写一大堆的downcast(as?)和可选(Optional),看?号都看花了.随后发现了这个库 ...

  9. ios开发网络学习三:NSURLConnection小文件大文件下载

    一:小文件下载 #import "ViewController.h" @interface ViewController ()<NSURLConnectionDataDele ...

随机推荐

  1. asp.net 组织结构图控件

    记得之前做项目的时候客户需要看一个组织结构图,从而了解一下公司的概况,本来自己之前没有做过这方面的控件,只好找度娘,出于对项目的完美,网上很多控件画面感比较渣,后来只能在这些个中挑个比较好的来做,先看 ...

  2. (转)IIS设置优化(需根据服务器性能,调整具体参数值)

    IIS7 优化-网站请求并发数>> /*调整IIS 7应用程序池队列长度*/队列长度 5000-20000(原来默认1000,最大65535,建议10000 ) /*调整IIS 7的app ...

  3. 10款很酷的HTML5动画和实用应用 有源码

    10款很酷的HTML5动画和实用应用,这里有菜单.SVG动画.Loading动画,总有你喜欢的,而且,每一款HTML5应用都提供源代码下载,方便大家学习和研究,一起来看看吧. 1.HTML5 SVG ...

  4. 判断不在Update Task中

    CALL FUNCTION 'TH_IN_UPDATE_TASK'   IMPORTING     IN_UPDATE_TASK = IN_UPDATE_TASK.  "0 then not ...

  5. 汇编语言-求X的阶乘

    1. 题目:求X的阶乘值 2. 要求:输入一个整型数(不超过10),求出其阶乘值后输出,求阶乘的算法用子程序来实现. 3. 提示:可以用递归来实现,也可以用简单的循环来实现. 这里使用循环来实现: 对 ...

  6. 例题6-4 Broken Keyboard UVa11988

    题目分析: 起初这道题目没有做出来,原因是我一直想把整块区域一并插入,而不是逐个插入.今后做题应该注意这个问题,把问题分解去考虑,也许会少走许多弯路. 下边附上AC代码 #include <cs ...

  7. mongodb 3.x WiredTiger存储优化测试

    http://pan.baidu.com/s/1sk8zekX 总结:1.使用WiredTiger引擎压缩比例约是MMAP引擎的12倍,2.从时间上看,此次测试100个线程并发,mongodb 3.2 ...

  8. node-mongo-native1.3.19连接mongo的最优方法

    最近需要在node下连接mongo,尝试了很多方法,本文简要总结一下 选择Driver 首先,基本上有4个常见的driver供选择 1.官方的是node-mongo-native 2.基于node-m ...

  9. php实现查询百度google收录情况(示例代码)

    对了貌似查google pr的东西只是file一个地址而已,如此说了就没有什么难度了.完整代码如下 写了一个小东西记录baidu和google对于站点的收录情况,现在可以查询了,其实也没什么难度,就是 ...

  10. smarty框架块函数

    块函数的形式是这样的:{func} .. {/func}.换句话说,它们被封闭在一个模板区域内,然后对该区域的内容进行操作.默认地,你的函数实现会被Smarty调用两次:一次是在开始标签,另一次是在闭 ...