最近在做一个小项目的时候,发现使用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. 使用Struts2 验证框架,验证信息重复多次出现

    版权声明:本文为博主原创文章,未经博主允许不得转载. 问题描述:第一次提交表单.某个数据不符合规则,就会出现一条错误信息.再次提交,上次显示的错误信息不消失,又多出一条一模一样的错误信息.提交几次,就 ...

  2. C# 谈Dictionary<TKey,TValue>,SortedDictionary<TKey,TValue>排序

    使用过Dictionary的人都知道,当每一个Add里面的值都不会改变其顺序,所以需要需要对其排序的时候就用到SortedDictionary, 但SortedDictionary并不是那么理想,其默 ...

  3. PowerDesigner提示This data item is already used in a primary identifier.的处理

    原文链接: http://blog.csdn.net/lopper/article/details/5293545 今天同事在编制一个数据库脚本的时候,提示了This data item is alr ...

  4. cookie+session,会话时间设定

    很多Web程序中第一次登录后,在一定时间内(如2个小时)再次访问同一个Web程序时就无需再次登录,而是直接进入程序的主界面(仅限于本机). 实现这个功能关键就是服务端要识别客户的身份.而用Cookie ...

  5. seajs构建方法

    标准构建 如果项目遵循推荐的标准目录结构: foo-module/   |-- dist                    //存放构建好的文件   |-- src                 ...

  6. HTML5-WebWorker

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  7. Linux 下安装服务器安全狗

    1.网上下载服务器安全狗的软件包    32位和64位 wget http://www.safedog.cn/server_safedog_linux.html/safedog_linux32.tar ...

  8. silverlight视频、音频

    几天发现MediaElement播放不了wav格式的音频文件,在网上找到一篇解决的文章: http://www.cnblogs.com/rupeng/archive/2011/02/20/195936 ...

  9. IIS6下, web.config配置为targetFramework="4.0"时出404错误

    打开IIS管理器,在"Web 服务扩展" 中 将ASP.NET v4.0设置为允许就好了.这个选项默认是禁止的.

  10. 客户端访问WebService和PageMethod

    客户端访问WebService 客户端访问WebService和后台访问WebService没什么不同,注意的地方是要在ScriptManager中添加 <Services>        ...