最近在做一个小项目的时候,发现使用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. 利用 Google API 调用谷歌地图 演示1

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. a标签替代input的submit提交功能

    在工作中有时候会遇到A标签,但是提交表单的时候我们需要用到submit来提交表单,下面几行代码很好的解决了这个问题! <div class="btn"><a hr ...

  3. 获取Class对象的方法及Class类型的一些讨论

    (1)Class.forName(className) (2)classname.Class 如果是数组,则是数组类型[].class (3)对象.getClass() 例: String path ...

  4. 2_1我的第一个应用hello world[wp8特色开发与编程技巧]

    2_1hello world -5min 大家好,我是徐文康,在上一个视频当中我们已经讲了,如何根据自己电脑系统去下载相应的SDK. 你可能花了很多时间去安装以及配置好了这个开发环境,如果还没有配置好 ...

  5. 【风马一族_Android】多选按钮的监控事件

    import android.app.Activity; import android.os.Bundle; import android.text.TextUtils; import android ...

  6. bootstrap2.3.2 modal 用href时有缓存

    $('body').on('hidden', '.modal', function () {$(this).removeData('modal');}); 直接在js里加入上面的代码就可以解决缓存问题 ...

  7. 使用C++读取UTF8及GBK系列的文本方法及原理

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4374404.html 1.读取UTF-8编码文本原理 首先了解UTF-8的编码方式,UTF- ...

  8. ubuntu下安装phpstudy环境记录

    下载一键安装包 下载地址:http://www.phpstudy.net/a.php/208.html 安装过程 开启终端 更改文件权限 chmod +x phpstudy 进行安装 ./phpstu ...

  9. 七天学会NodeJS-学习笔记

    在网上发现一篇nodeJS教程,名为七天学会NodeJS,标题很有吸引力.我不指望七天能学会,只希望可以入门,下面是我的学习笔记和遇到的问题. 教程网址:http://nqdeng.github.io ...

  10. js学习笔记一类型、值和变量

    js的数据类型分为两类:原始类型和对象类型 原始类型包括数字.字符串和布尔值 js中有2个特殊的原始值:null(空)和undefined(未定义) 对象是属性的集合,每个属性都由名/值对组成 js的 ...