MKNetworkKit的断点续传SIDownloader下载
comefrom:http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f73d6f8b9042238fce0984642c101a39fefd60644d44889622261cf31e1aafad762b2a0322b49bd58b49debe8f2e248230340746c01e4cc75cf28b102a9e79cc0dafea44a7e3e733e3f78995c85422910e446d80819c2a7303be6ee76540f4d5935f142f07ca9c27148e4e012b88574aa14689f7431a10f0f6ca2a4ad45cda&p=8d7fc54ad5c34bf70be2962c444188&newp=9a769a4786cc42af52ad886d15088e231610db2151d6da&user=baidu&fm=sc&query=mknetworkkit+ios+%BA%F3%CC%A8%BC%CC%D0%F8%CF%C2%D4%D8&qid=c53ebf38000a5837&p1=1
https://github.com/MugunthKumar/MKNetworkKit
使用MKNetworkKit
- 首先把clone下来的MKNetworkKit文件夹拖进你的项目里面
- 到项目里面增加CFNetwork.Framework SystemConfiguration.framework 和 Security.framework.
- 把MKNetworkKit.h包含到你的pch文件里面。
- 如果是 如果是Mac,删除UIAlertView+MKNetworkKitAdditions.h这个文件
这样,再看看介绍里面的例子。应该就能看懂普通用法了。然后畅快的使用MKNetworkKit库了。
改写目标
上次写的ASIHTTPRequest续传其实已经可以用了。但是为什么需要重新写呢。就是重用!!!
一直都很少自己设计接口什么的。其实只是做了写体力的劳动,把一堆逻辑换成代码给堆了起来。觉得没有人会去重用自己的代码。很少去花心思想怎么样才能写好。
这次改写就只有一个目标,为了更好更多人能使用断点续传来 功能
下载应该在下载继续进行。
保持进度条
每次进入 暂停恢复 可以随时暂停下载
这次改写,这些功能都实现了,啊哈哈哈。
实现
MKNetworkKit库修改
最开始使用MKNetworkKit库做
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
  NSUInteger size = [self.response expectedContentLength] < 0 ? 0 : [self.response expectedContentLength];
  self.response = (NSHTTPURLResponse*) response;
  // dont' save data if the operation was created to download directly to a stream.
  if([self.downloadStreams count] == 0)
    self.mutableData = [NSMutableData dataWithCapacity:size];
  else
    self.mutableData = nil;
  for(NSOutputStream *stream in self.downloadStreams)
    [stream open];
  NSDictionary *httpHeaders = [self.response allHeaderFields];
  // if you attach a stream to the operation, MKNetworkKit will not cache the response.
  // Streams are usually "big data chunks" that doesn't need caching anyways.
  if([self.request.HTTPMethod isEqualToString:@"GET"] && [self.downloadStreams count] == 0) {
    // We have all this complicated cache handling since NSURLRequestReloadRevalidatingCacheData is not implemented
    // do cache processing only if the request is a "GET" method
    NSString *lastModified = [httpHeaders objectForKey:@"Last-Modified"];
    NSString *eTag = [httpHeaders objectForKey:@"ETag"];
    NSString *expiresOn = [httpHeaders objectForKey:@"Expires"];
    NSString *contentType = [httpHeaders objectForKey:@"Content-Type"];
    // if contentType is image,
    NSDate *expiresOnDate = nil;
    if([contentType rangeOfString:@"image"].location != NSNotFound) {
      // For images let's assume a expiry date of 7 days if there is no eTag or Last Modified.
      if(!eTag && !lastModified)
        expiresOnDate = [[NSDate date] dateByAddingTimeInterval:kMKNetworkKitDefaultImageCacheDuration];
      else
        expiresOnDate = [[NSDate date] dateByAddingTimeInterval:kMKNetworkKitDefaultImageHeadRequestDuration];
    }
    NSString *cacheControl = [httpHeaders objectForKey:@"Cache-Control"]; // max-age, must-revalidate, no-cache
    NSArray *cacheControlEntities = [cacheControl componentsSeparatedByString:@","];
    for(NSString *substring in cacheControlEntities) {
      if([substring rangeOfString:@"max-age"].location != NSNotFound) {
        // do some processing to calculate expiresOn
        NSString *maxAge = nil;
        NSArray *array = [substring componentsSeparatedByString:@"="];
        if([array count] > 1)
          maxAge = [array objectAtIndex:1];
        expiresOnDate = [[NSDate date] dateByAddingTimeInterval:[maxAge intValue]];
      }
      if([substring rangeOfString:@"no-cache"].location != NSNotFound) {
        // Don't cache this request
        expiresOnDate = [[NSDate date] dateByAddingTimeInterval:kMKNetworkKitDefaultCacheDuration];
      }
    }
    // if there was a cacheControl entity, we would have a expiresOnDate that is not nil.
    // "Cache-Control" headers take precedence over "Expires" headers
    expiresOn = [expiresOnDate rfc1123String];
    // now remember lastModified, eTag and expires for this request in cache
    if(expiresOn)
      [self.cacheHeaders setObject:expiresOn forKey:@"Expires"];
    if(lastModified)
      [self.cacheHeaders setObject:lastModified forKey:@"Last-Modified"];
    if(eTag)
      [self.cacheHeaders setObject:eTag forKey:@"ETag"];
  }
    if ([self.mutableData length] == 0 || [self.downloadStreams count] > 0) {
        // This is the first batch of data
        // Check for a range header and make changes as neccesary
        NSString *rangeString = [[self request] valueForHTTPHeaderField:@"Range"];
        if ([rangeString hasPrefix:@"bytes="] && [rangeString hasSuffix:@"-"]) {
            NSString *bytesText = [rangeString substringWithRange:NSMakeRange(6, [rangeString length] - 7)];
            self.startPosition = [bytesText integerValue];
            self.downloadedDataSize = self.startPosition;
            DLog(@"Resuming at %d bytes", self.startPosition);
        }
    }
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
  if([self.downloadStreams count] == 0)
    [self.mutableData appendData:data];
  for(NSOutputStream *stream in self.downloadStreams) {
    if ([stream hasSpaceAvailable]) {
      const uint8_t *dataBuffer = [data bytes];
      [stream write:&dataBuffer[0] maxLength:[data length]];
    }
  }
  self.downloadedDataSize += [data length];
  for(MKNKProgressBlock downloadProgressBlock in self.downloadProgressChangedHandlers) {
    if([self.response expectedContentLength] > 0) {
      double progress = (double)(self.downloadedDataSize) / (double)(self.startPosition + [self.response expectedContentLength]);
      downloadProgressBlock(progress);
    }
  }
}
具体改了哪,忘记了。有心思对照源码看看。应该是属于MKNetworkKit的bug。也不知道新版改过来没有。但是你clone我的demo,这个版本是可以的。
断点 其实我一共就写了两个简单的类而已。
基础的是SIBreakpointsDownload。继承于MKNetworkOperation。判断了续传的位置。
一个SIDownloadManager写成单例,继承于MKNetworkEngine。用来管理多任务 使用的时候就只用SIDownloadManager这个类来添加下载。然后想在 demo地址
git@github.com:iiiyu/SIDownloader.git
其实已经很简单了,照着demo改改就能自己用了。
总结
这次改写以后,代码结构变的很清晰。复杂性和耦合性都有所降低。可用性提高。而且,反正我是没有google到可以直接拿来用的断点ios代码库-www.lanrenios.com
MKNetworkKit的断点续传SIDownloader下载的更多相关文章
- python多进程断点续传分片下载器
		python多进程断点续传分片下载器 标签:python 下载器 多进程 因为爬虫要用到下载器,但是直接用urllib下载很慢,所以找了很久终于找到一个让我欣喜的下载器.他能够断点续传分片下载,极大提 ... 
- Android的断点续传的下载在线文件示例
		Android的断点续传的下载在线文件示例 文件的结构如下: activity_main.xml: <LinearLayout xmlns:android="http://schema ... 
- C#: 实现支持断点续传多线程下载
		/* .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (C# DIY HttpWebClient)* Reflector 了一下 System.Net.WebClien ... 
- http文件的断点续传和下载
		http://www.tuicool.com/articles/ZbyymqJ Content-Disposition:inline; filename= "c501b_01_h264_sd ... 
- Java-->实现断点续传(下载)
		--> 断点续传: 就像迅雷下载文件一样,停止下载或关闭程序,下次下载时是从上次下载的地方开始继续进行,而不是重头开始... --> RandomAccessFile --> poi ... 
- asp.net断点续传技术---下载(转)
		断点续传的原理 在了解HTTP断点续传的原理之前,先来说说HTTP协议,HTTP协议是一种基于tcp的简单协议,分为请求和回复两种.请求协议是由客户机(浏览器)向服务器(WEB SERVER)提交请求 ... 
- java实现文件的断点续传的下载
		java的断点续传是基于之前java文件下载基础上的功能拓展 首先设置一个以线程ID为名的下载进度文件, 每一次下载的进度会保存在这个文件中,下一次下载的时候,会根据进度文件里面的内容来判断下载的进度 ... 
- Android 多线程断点续传同时下载多个大文件
		最近学习在Android环境中一些网络请求方面的知识,其中有一部分是关于网络下载方面的知识.在这里解析一下自己写的demo,总结一下自己所学的知识.下图为demo的效果图,仿照一些应用下载商城在Lis ... 
- 用java实现文件的断点续传并发下载
		需求: 支持文件批量下载.现在有很多小图片需要批量下载,不希望在服务器打包下载. 支持大文件断点下载.比如下载10G的文件. PC端全平台支持.Windows,macOS,Linux 全浏览器支持.i ... 
随机推荐
- ua识别(浏览器标识识别)
			ua识别(浏览器标识识别) 一.总结 1.浏览器标识(UA):可以使得服务器能够识别客户使用的操作系统及版本.CPU 类型.浏览器及版本.浏览器渲染引擎.浏览器语言.浏览器插件,从而判断用户是使用电脑 ... 
- 2.写给设计师看的HTML&CSS入门指导
			转自:http://www.uisdc.com/html-and-css-guide 整体简介 在开始学习HTML&CSS之前,首先要搞清楚两者的区别.两者在整体上有着很明显的差异. 整体看来 ... 
- Python产生随机数组,测试用
			import numpy as np if __name__ == '__main__': a=np.random.randint(0,10,size=[3,3]) print(a) 输出: [ ... 
- SoapUI、Jmeter、Postman三种接口测试工具的比较分析——灰蓝
			前段时间忙于接口测试,也看了几款接口测试工具,简单从几个角度做了个比较,拿出来与诸位分享一下吧.各位如果要转载,请一定注明来源,最好在评论中告知博主一声,感谢.本报告从多个方面对接口测试的三款常用工具 ... 
- 如何把别人的原理图和pcb图建立一个完整的工程
			这里是我从网友那里下载的pcb图和原理图 我们怎么通过这两个文件建立一个完整的工程 我们选中pcb图文件,通过下面的操作,就可以导出pcb封装库: 同样的方法,我选中pcb图,然后用下面图的方法,就可 ... 
- jQuery weui Select组件显示指定值
			jQuery weui有个支持单选或者多选的select弹出层,默认他是这样的 第2部分选择什么值,第1部分就显示什么值,一般的场景支持是没问题了,但本次开发碰到了一个问题. 需求描述: 职业名称后面 ... 
- [Math Processing Error] 问题的解决(F5刷新页面与 Ctrl/Shift + F5 刷新页面的区别)
			Why is [Math Processing Error] all over the place today? 当打开某页面出现 [Math Processing Error],一般表示 MathJ ... 
- 剪枝法观点下的旅行商问题(TSP)
			1. 构建基本的穷举搜索骨架 int n; int dst[100][100]; int best; const int INF = 987654321; // 初始状态下,path 存入第一节点,v ... 
- 关于win10输入法ctrl+shift+f和idea组合键冲突的解决办法。
			先Ctrl+F,按住Ctrl,再按Shift+F. 因为win10的输入法热键无法关闭(在后期的版本中好像可以了,不过没更新),在IEDA中ctrl+shift+f组合键没法使用,可以按如下按键组合使 ... 
- 制作Kinect体感控制小车教程 <一>
			转载请注明出处:http://blog.csdn.net/lxk7280 Kinect体感控制小车 Kine ... 
