zoukankan      html  css  js  c++  java
  • iOS基础

    一、iOS网络层次结构

    基于iOS提供API实现上传文件和断点续传的思路

    常用iOS第三方网路框架简介

    AFNetworkingAFN

    ASIHTTPRequestASI

    另外一个常用框架

    SSZipArchive

    二、iOS网络编程层次结构

    Cocoa层(NSURLBonjourGame KitWebKit

    Core Foundation层(基于 的 CFNetwork 和 CFNetServices

    OS层(基于 的 BSD socket

    三、iOS网络编程层次结构概述

    Cocoa层:是最上层的基于OCAPI,比如URL访问,NSStreamBonjourGameKit等,这是大多数情况下我们常用的 APICocoa层是基于Core Foundation实现的

    Core Foundation层:基于C语言的框架,因为直接使用socket需要更多的编程工作,所以苹果对OS层的socket进行简单的封装以简化编程任务。该层提供了CFNetworkCFNetServices,其中CFNetwork又是基于CFStreamCFSocket

    OS层:最底层的BSD socket提供了对网络编程最大程度的控制,但是编程工作也是最多的。苹果建议我们使用Core Foundation及以上层的API进行编程。BSDUNIX系统中通用的网络接口,它不仅支持各种不同的网络类型,而且也是一种内部进程之间的通信机制

    四、AFN vs ASI

    AFN

    官方推荐的使用方法:为一系列相关的请求定义一个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作为网络底层控件。

    六、AFNetworkingAFN

    下载地址

    https://github.com/AFNetworking/AFNetworking

    AFNetworking官网地址:

    http://afnetworking.com

    七、导入AFN框架的步骤

    1. 将框架程序拖拽进项目

    2.  添加iOS框架引用

    SystemConfiguration.framework

    MobileCoreServices.framework

    3. 修改xxx-Prefix.pch文件

    #import <MobileCoreServices/MobileCoreServices.h>

    #import <SystemConfiguration/SystemConfiguration.h>

    八、AFHTTPClient

    1. 建立NSURLRequest

    创建GETHEADPUTDELETE方法请求

    requestWithMethod:path:parameters:

    创建POST方法请求

    multipartFormRequestWithMethod:path:parameters: constructingBodyWithBlock:

    2. 检测网路连接状态

    setReachabilityStatusChangeBlock

    九、AFHttpRequestOperationNSURLConnection的封装

    AFHttpRequestOperation HTTP请求操作

    AFJSONRequestOperation 对JSON请求的封装

    AFXMLRequestOperation 对XML请求的封装

    AFPropertyListRequestOperation 对Plist请求的封装

    AFImageRequestOperation 对图像请求的封装

    块代码操作

    setCompletionBlockWithSuccess 设置请求完成块代码

    setUploadProgressBlock 设置上传进度块代码

    setDownloadProgressBlock 设置下载进度块代码

    下载操作需要设置outputStream

    针对请求的操作pause(暂停)resume(继续)

    十、检测网络连接状态

    AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:@"http://www.baidu.com"]];

    [client setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {

    }];

    十一、加载JSON & XML

    AFJSONRequestOperation *op = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

        NSLog(@"%@", JSON);

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {

        NSLog(@"%@", JSON);

    }];

    十二、上传图像

    NSURLRequest *request = [client multipartFormRequestWithMethod:@"POST" path:@"/~liufan9/itcast/upload.php" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

        [formData appendPartWithFileData:imageData name:@"file" fileName:@"update.png" mimeType:@"image/png"];

    }];

    // 定义操作

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request];

    // 设置上传

    // 设置下载进度

    十三、解压缩——另一个第三方框架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];

    十四、ASIHTTPRequestASI

    使用ASI的两点注意事项

    ASI框架是不支持ARC

    ASI框架是基于iOS5.0的,如果选择iOS6.0会有一些苹果官方不再维护的方法

    十五、ASI下载文件的准备工作

    // 1. 指定下载文件地址

    NSString *string = @"http://localhost/~liufan9/itcast/download/iTunesConnect_DeveloperGuide_CN.zip";

    NSURL *url = [NSURL URLWithString:string];

    // 2. 设定文件保存路径及缓存路径

    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *downloadPath = [documents[0]stringByAppendingPathComponent:@"book.zip"];

    NSString *tempPath = [documents[0]stringByAppendingPathComponent:@"book.tmp"];

    十六、ASI 下载文件请求定义部分代码

    // 3. 创建ASIHTTPRequest

    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

    // 4. 设置代理——ASI是通过代理回调的方式处理网络请求的

    [request setDelegate:self];

    // 5. 设置下载路径

    [request setDownloadDestinationPath:downloadPath];

    // 6. 设置缓存路径

    [request setTemporaryFileDownloadPath:tempPath];

    // 7. 设置断点续传

    [request setAllowResumeForFileDownloads:YES];

    // 8. 设置下载进程代理

    [request setDownloadProgressDelegate:self];

    // 9. 启动异步请求——用户想知道下载的实际进展情况

    [request start];

    十七、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

    对比结果:

    ASIRequest不需要处理中间数据

    但是请求开始拆分成了两部分

    十九、实现代理方法之前需要先遵从代理协议

     

    ASIHTTPRequestDelegate

    ASIProgressDelegate

    二十、第三方框架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 解压缩

    [SSZipArchive unzipFileAtPath:downloadPath toDestination:unzipPath];

     

    // 3. 删除压缩文件

    [[NSFileManager defaultManager]removeItemAtPath:downloadPath error: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);

     

  • 相关阅读:
    什么是线程安全和线程不安全
    C# 实现Dictionary数据对象的深度拷贝
    数据库设计三大范式
    Socket 短连接、长连接
    第二篇:MongoDB高级查询
    如何在oracle中导入导出dmp数据库文件
    以太网中的UDP编程:udp分包问题
    CocosBuilder 值得关注的一个新项目
    [转载]iPhone程序到iPad程序的移植问题
    DWR使用总结
  • 原文地址:https://www.cnblogs.com/monicaios/p/3527640.html
Copyright © 2011-2022 走看看