• 第三方框架


    iOS网络层次结构基于iOS提供API实现上传文件和断点续传的思路
    常用iOS第三方网路框架简介-AFNetworking(AFN)-ASIHTTPRequest(ASI)
    另外一个常用框架-SSZipArchive
    ANF使用演示

    目标
    iOS网络层次结构基于iOS提供API实现上传文件和断点续传的思路
    常用iOS第三方网路框架简介-AFNetworking(AFN)-ASIHTTPRequest(ASI)
    另外一个常用框架-SSZipArchive
    ANF使用演示

    iOS网络编程层次结构示意图



    Cocoa(NSURL,Bonjour,Game Kit,WebKit)

         Core Foundation
    (基于CCFNetworkCFNetServices)

    OS(基于CBSD socket)
    iOS网络编程层次结构示意图

    iOS网络编程层次结构概述
    Cocoa:是最上层的基于OCAPI,比如URL访问,NSStream,Bonjour,GameKit等,这是大多数情况下我们常用的APICocoa层是基于Core Foundation实现的
     Core Foundation:基于C语言的框架,因为直接使用socket需 要更多的编程工作,所以苹果对OS层的socket进行简单的封装 以简化编程任务。该层提供了CFNetworkCFNetServices,其 中CFNetwork又是基于CFStreamCFSocket
     OS:最底层的BSD socket提供了对网络编程最大程度的控制, 但是编程工作也是最多的。苹果建议我们使用Core Foundation及以上层的API进行编程。BSDUNIX系统中通用的网络接口, 它不仅支持各种不同的网络类型,而且也是一种内部进程之间 的通信机制

    不使用第三方框架如何实现文件上传?
    使用NSURLConnection无法通过HTML表单来上传 图片,因此想要上传图片,必须实现HTTP请求, 而不能像其他语言那样通过HTML表单的POST就 能上传


    不使用第三方框架如何实现断点续传?
     要使用NSURLConnection实现断点续传
     需要自定义URLRequest的头部的Range属性,通知URLConnection只是 去获取部分网络内容

     Range头域示例
     Range头域可以请求实体的一个或者多个子范围。例如,
     表示头500个字节:bytes=0-499
     表示第二个500字节:bytes=500-999
     表示最后500个字节:bytes=-500
     表示500字节以后的范围:bytes=500-
     第一个和最后一个字节:bytes=0-0,-1
     同时指定几个范围:bytes=500-600,601-999
     但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响 应会以状态码206(PartialContent)返回而不是以200(OK)

    为什么要选择第三方框架
    第三方框架把复杂的网络底层操作封装成友好的类和方法,并且加入 异常处理等,从而可以:
    -高效的与服务端API进行数据交换-提高开发效率和稳定性
    选择第三方框架的原则1.是否被广泛使用,有足够多得大牛验证过
    2.尽量保证能够看懂其中的所有代码3.可以学习编写其中部分方法,但是不要去直接修改

    常用的iOS网络开发框架
    AFNetworking(AFN)
    ASIHTTPRequest(ASI)HTTP终结者,非ARC
    备注:201210ASI停止更新,但这并不意味着ASI的应用已经停止

    AFN vs ASIAFN:
    - 官方推荐的使用方法:为一系列相关的请求定义一个HTTPClient,共用一个BaseURL。每次请求把URL中除BaseURLPath部分做为参数传给HTTPClient的静态方法,并注册一个Block用于回调
    - 基于NSURL,性能和稳定性略差
    - AFN只封装了一些常用功能,满足基本需求,而直接忽略了很多扩展功能
    - 针对JSONXMLPListImage四种数据结构封装了各自处理器,开发者可 以把处理器注册到操作队列中,直接在回调方法中获得格式化以后的数据
    ASI:
    - 推荐使用方法:每一个请求都由构造方法初始化一个(共享)实例,通过这 个实例配置参数并发起请求。ASI最初使用delegate模式回调,在iOS SDK支持Block之后也提供了注册Block的实例方法(注:ASIBlock不易使用)
    - 基于CFNetwork,性能和稳定性略高
    - ASI的扩展功能非常丰富
    - ASI没有针对任何数据类型做特别封装,只是预留了各种接口和工具供开发者 自行扩展

    AFNASI的选择
    AFN适合逻辑简单的应用,或者更适合开发资源尚不丰富的团队,因 为AFN易用性要比ASI好很多,而这样的应用(或团队)对底层网络 控件的定制化要求也非常低。
    ASI更适合已经发展了一段时间的应用,或者开发资源相对丰富的团 队,因为往往这些团队(或他们的应用)已经积累了一定的经验,无 论是产品上还是技术上的。需求复杂度就是在这种时候高起来,而且 底层订制的需求也越来越多,此时AFN就很难满足需求,需要牺牲一 定的易用性,使用ASI作为网络底层控件。

    AFNetworking(AFN)下载地址
    https://github.com/AFNetworking/AFNetworking
    AFNetworking官网地址:http://afnetworking.com
    新建项目并导入ANF框架的步骤演练

    新建项目并导入AFN框架的步骤
    1.将框架程序拖拽进项目2.添加iOS框架引用
    -SystemConfiguration.framework
    -MobileCoreServices.framework3.修改xxx-Prefix.pch文件
    #import#import

    AFN--AFHTTPClient
     1.使用baseURL实例化
     2.建立NSURLRequest
    Ø创建GETHEADPUTDELETE方法请求
    ²requestWithMethod:path:parameters:
    Ø创建POST方法请求
    ²multipartFormRequestWithMethod:path:parameters: constructingBodyWithBlock:
     3.检测网路连接状态-setReachabilityStatusChangeBlock

    AFHttpRequestOperation--NSURLConnection的封装
    AFHttpRequestOperation HTTP请求操作ØAFJSONRequestOperationJSON请求的封装ØAFXMLRequestOperationXML请求的封装ØAFPropertyListRequestOperationPlist请求的封装ØAFImageRequestOperation对图像请求的封装
    块代码操作ØsetCompletionBlockWithSuccess设置请求完成块代码
    ØsetUploadProgressBlock设置上传进度块代码ØsetDownloadProgressBlock设置下载进度块代码
    下载操作需要设置outputStream
    Ø针对请求的操作pause(暂停)resume(继续)

    检测网络连接状态
    AFHTTPClient*client = [AFHTTPClientclientWithBaseURL:[NSURLURLWithString:@"http://www.baidu.com"]];
    [clientsetReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatusstatus) { }];

    加载JSON & XML
    AFJSONRequestOperation*op = [AFJSONRequestOperationJSONRequestOperationWithRequest:requestsuccess:^(NSURLRequest*request,NSHTTPURLResponse*response,idJSON) {
    NSLog(@"%@", JSON);
    }
    failure:^(NSURLRequest*request,NSHTTPURLResponse*response,NSError*error,id
    JSON) {
    NSLog(@"%@", JSON);
    }];

    上传图像
    NSURLRequest*request = [clientmultipartFormRequestWithMethod:@"POST"path:@"/~liufan9/ itcast/upload.php"parameters:nilconstructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    [formDataappendPartWithFileData:imageDataname:@"file"fileName:@"update.png"mimeType:@"image/png"];
    }];
    //定义操作AFHTTPRequestOperation*operation = [[AFHTTPRequestOperation
    alloc]initWithRequest:request];//设置上传//设置下载进度

    演练(6)--断点续传设置操作的输出流(在网络中的数据是流的方式传输)
    [operationsetOutputStream:[NSOutputStreamoutputStreamToFileAtPath:downloadPathappend:YES]];

    解压缩--另一个第三方框架SSZipArchive
    下载地址:https://github.com/samsoffes/ssziparchive
    注意:需要引入libz.dylib框架
    // Unzipping
    NSString*zipPath=@"path_to_your_zip_file";
    NSString
    *destinationPath=@"path_to_the_folder_where_you_want_it_unzipped"; [SSZipArchive unzipFileAtPath:zipPath toDestination:destinationPath];
    // Zipping
    NSString*zippedPath=@"path_where_you_want_the_file_created"; NSArray*inputPaths=[NSArray arrayWithObjects:

    [[NSBundle mainBundle] pathForResource:@"photo1"ofType:@"jpg"], [[NSBundle mainBundle] pathForResource:@"photo2"ofType:@"jpg"]nil];
    [SSZipArchive createZipFileAtPath:zippedPath withFilesAtPaths:inputPaths];
    ASIHTTPRequest(ASI)
    下载地址
    http://github.com/pokeb/asi-http-request/tarball/master
    新建项目并导入ASI框架的步骤演练:
    -从服务器下载文件并解压缩

    使用ASI的两点注意事项
    ASI框架是不支持ARC
    ASI框架是基于iOS5.0的,如果选择iOS6.0会有一些苹果官方不再维护 的方法

    新建项目并导入ASI框架的步骤(1)
    新建项目,不选择ARC支持Deployment Target修改为5.0
    ASI解压缩包中的以下两个文件夹拖入项目
    -Classes-External

    新建项目并导入ASI框架的步骤(2)
    编译出现错误:ASIWebPageRequest.m:13:9: 'libxml/HTMLparser.h' file not found
    错误原因:-无法正确找到libxml/HTMLparser.h
    解决方法:-在头文件搜索目录中添加:${SDK_DIR}/usr/include/libxml2

    添加搜索路径示意图


    新建项目并导入ASI框架的步骤(3)编译出现错误:
    ASITestCase.h:12:9: 'GHUnitIOS/GHUnit.h' file not found
    错误原因:没有GHUnit框架解决办法:删除单元测试部分的代码引用


    删除单元测试代码引用示意图


    新建项目并导入ASI框架的步骤(4)编译:



    85个错误
    瞬间凌乱有木有~~~
    新建项目并导入ASI框架的步骤(4)
    解决方法:添加以下iOS框架引用-CFNetwork.framework
    -SystemConfiguration.framework-MobileCoreServices.framework-libz.dylib
    -libxml2.dylib
    怎么知道需要这些框架?



    编译通过 

    ASI断点续传实现思路回顾
    目标:使用断点续传的方式下载zip文件并解压缩思路:
    1.指定下载文件地址2.设定文件保存路径及缓存路径3.创建ASIHTTPRequest
    4.
    设置代理--ASI是通过代理回调的方式处理网络请求的5.设置下载路径6.设置缓存路径7.设置断点续传8.设置下载进程代理--用户想知道下载的实际进展情况9.启动异步请求

    ASI下载文件的准备工作--源和目标

    // 1.指定下载文件地址
    NSString*string =@"http://localhost/~liufan9/itcast/download/iTunesConnect_DeveloperGuide_CN.zip";
    NSURL*url = [NSURLURLWithString:string]; 
    // 2.设定文件保存路径及缓存路径
    NSArray*documents =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
    NSString*downloadPath = [documents[0]stringByAppendingPathComponent:@"book.zip"];
    NSString*tempPath = [documents[0]stringByAppendingPathComponent:@"book.tmp"];

    ASI下载文件请求定义部分代码
    // 3.创建ASIHTTPRequestASIHTTPRequest*request = [ASIHTTPRequestrequestWithURL:url]; // 4.设置代理--ASI是通过代理回调的方式处理网络请求的[requestsetDelegate:self];
    // 5.设置下载路径[requestsetDownloadDestinationPath:downloadPath];
    // 6.设置缓存路径[requestsetTemporaryFileDownloadPath:tempPath];
    // 7.设置断点续传[requestsetAllowResumeForFileDownloads:YES];
    // 8.设置下载进程代理[requestsetDownloadProgressDelegate:self];
    // 9.启动异步请求--用户想知道下载的实际进展情况[requeststart];

    NSURLConnectionDataDelegate的代理方法回顾
    //服务器开始返回数据-(void)connection:didReceiveResponse: //收到服务器返回的数据,本方法会被调用多次- (void)connection:didReceiveData:
    //数据接收完毕-(void)connectionDidFinishLoading:
    //网络连接错误- (void)connection:didFailWithError: //发送数据给服务器,POST请求使用此方法
    - (void)connection:didSendBodyData:totalBytesWritten: totalBytesExpectedToWrite:

    ASIRequest代理方法
    //请求开始
    - (void)requestStarted:(ASIHTTPRequest*)request
    //请求接收到响应的头部,包括文件大小信息
    - (void)request:(ASIHTTPRequest*)request didReceiveResponseHeaders: (NSDictionary*)responseHeaders
    //请求完成- (void)requestFinished:(ASIHTTPRequest*)request
    //请求失败- (void)requestFailed:(ASIHTTPRequest*)request对比结果:1.ASIRequest不需要处理中间数据2.但是请求开始拆分成了两部分


    实现代理方法之前需要先遵从代理协议
    1.ASIHTTPRequestDelegate 2.ASIProgressDelegate

    ASIRequest代理方法实现(1)
    给四个代理方法添加NSLog,看看都在干什么目的:运行根据Log结果写思路请求头部可以看到文件长度,思路如下:
    // 2.发现其中有一个"Content-Length" = 6105204;//貌似是和文件下载进度有关的工作可以在这里进行//暂时先放一下
    请求完成://需求:
    // 1.知道文件保存路径// 2.解压缩文件// 3.删除压缩文件


    下一目标解压缩文件
    运行看看文件来了吗?

    解压缩--另一个第三方框架SSZipArchive下载地址:https://github.com/samsoffes/ssziparchive
    注意:需要引入libz.dylib框架
    // Unzipping
    NSString*zipPath=@"path_to_your_zip_file";
    NSString
    *destinationPath=@"path_to_the_folder_where_you_want_it_unzipped"; [SSZipArchive unzipFileAtPath:zipPath toDestination:destinationPath];
    // Zipping
    NSString*zippedPath=@"path_where_you_want_the_file_created"; NSArray*inputPaths=[NSArray arrayWithObjects:

    [[NSBundle mainBundle] pathForResource:@"photo1"ofType:@"jpg"], [[NSBundle mainBundle] pathForResource:@"photo2"ofType:@"jpg"]nil];
    [SSZipArchive createZipFileAtPath:zippedPath withFilesAtPaths:inputPaths];
    请求完成部分代码实现
    NSLog(@"请求完成");
    //需求:// 1.知道文件保存路径(运行,发现文件已经下载完成了)// 2.解压缩文件(导入SSZipArchive框架)//根据SSZipArchive框架用法写思路// 2.1设置压缩文件路径
    NSArray*documents =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
    NSString*downloadPath = [documents[0]stringByAppendingPathComponent:@"book.zip"];
    // 2.2设置解压缩文件路径,保存在当前路径NSString*unzipPath = documents[0];
    // 2.3解压缩[SSZipArchiveunzipFileAtPath:downloadPathtoDestination:unzipPath];
    // 3.删除压缩文件
    [[NSFileManagerdefaultManager]removeItemAtPath:downloadPatherror:nil];

    下载进度跟踪--ASIProgressDelegate下一目标

    ASIProgressDelegate--setProgress
    #pragma mark -下载进度代理方法- (void)setProgress:(float)newProgress {
    //通过Log发现传入的是一个百分比的数组//现在需要一个文件大小,并提示用户文件的大小
    NSLog(@"%f", newProgress); }

    ASIRequest响应头部的代码实现
    1. ASIRequest响应头部的代码实现
    // 1. NSLOG
    看看头部是什么内容NSLog(@"%@", responseHeaders);
    // 2.发现其中有一个"Content-Length" = 6105204;//貌似是和文件下载进度有关的工作可以在这里进行//将文件大小转换成M为单位 字节-K-M_fileLength= request.contentLength/1024.0/1024.0;NSLog(@"%.2fM",_fileLength);
    2. setProgress方法NSLog(@"%.2f", newProgress *_fileLength); 

    ASI框架小结
     ASI框架是不支持ARC
     ASI框架是基于iOS5.0
     使用前的准备工作有点繁琐
     目前有不少的公司在使用ASI框架,不过大多新的项目已经转用AFN框 架
     201210ASI停止更新,但这并不意味着ASI的应用已经停止
     学习也是需求驱动的,知道了ASI框架的基础用法后,今后工作中如 果需要,可以针对具体知识点去谷歌+度娘

    关于第三方框架的小结
    第三方框架把复杂的网络底层操作封装成友好的类和方法,并且加入异常处 理等,从而可以:
    -高效的与服务端API进行数据交换
    -提高开发效率和稳定性选择第三方框架的原则


    1.尽量保证能够看懂其中的所有代码2.是否被广泛使用3.可以学习编写其中部分方法,但是不要去直接修改
    常用的iOS网络开发框架-AFN适合逻辑简单的应用,基于NSURL
    -ASI更适合已经发展了一段时间的应用,基于CFNetwork已停止更新
    不要视图完全吃透了再去使用,可以针对具体知识点去谷歌+度娘

  • 相关阅读:
    [iOS]delegate和protocol
    Objective-c中@interface、@implementation、@protocal
    iOS应用的真机调试
    2016最新Java笔试题集锦
    Java面试题相关内容
    JSP面试题及答案
    JAVA面试题相关基础知识
    mysql workbench建表时PK,NN,UQ,BIN,UN,ZF,AI
    Java中equals和==的区别
    java的Arrays类的应用
  • 原文地址:https://www.cnblogs.com/zhangyang17/p/3574473.html
Copyright © 2020-2023  润新知