详解iOS - ASIHTTPRequest 网络请求

前言

使用 iOS SDK 中的 HTTP 网络请求 API,相当的复杂,调用很繁琐,ASIHTTPRequest 就是一个对 CFNetwork API 进行了封装,并且使用起来非常简单的一套 API,外号 “HTTP终结者”,用 Objective-C 编写,运行效率很高,可以很好的应用在 Mac OS X 系统和 iOS 平台的应用程序中,ASIHTTPRequest 适用于基本的 HTTP 请求,和基于 REST 的服务之间的交互。可惜作者早已停止更新,有一些潜在的 BUG 无人去解决,很多公司的旧项目里面都残留着它的身影,以前的很多 iOS 项目都是 ASI + SBJson,会不会用 ASI,可以算是检验是否为老牌 iOS 程序员的标准之一。从 iOS 9 开始 CFNetwork 相关的类和方法开始被废弃,可以使用 AFNetworking 替换 ASIHTTPRequest 的使用。在 iOS 9+ 中使用 ASIHTTPRequest 无需对 App Transport Security Settings 添加设置。

1、ASIHTTPRequest

1.1 ASI 主要特色

  • 通过简单的接口,即可完成向服务端提交数据和从服务端获取数据的工作。
  • 下载的数据,可存储到内存中或直接存储到磁盘中。
  • 能上传本地文件到服务端。
  • 可以方便的访问和操作请求和返回的 Http 头信息。
  • 可以获取到上传或下载的进度信息,为应用程序提供更好的体验。
  • 支持上传或下载队列,并且可获取队列的进度信息。
  • 支持基本、摘要和 NTLM 身份认证,在同一会话中授权凭证会自动维持,并且可以存储在 Keychain(Mac 和 iOS 操作系统的密码管理系统)中。
  • 支持 Cookie。
  • 当应用(iOS 4+)在后台运行时,请求可以继续运行。
  • 支持 GZIP 压缩数据。
  • 内置的 ASIDownloadCache 类,可以缓存请求返回的数据,这样即使没有网络也可以返回已经缓存的数据结果。
  • ASIWebPageRequest 可以下载完整的网页,包括包含的网页、样式表、脚本等资源文件,并显示在 UIWebView /WebView 中。任意大小的页面都可以无限期缓存,这样即使没有网络也可以离线浏览。
  • 支持客户端证书。
  • 支持通过代理发起 Http 请求。
  • 支持带宽限制。在 iOS 平台,可以根据当前网络情况来自动决定是否限制带宽,例如当使用 WWAN(GPRS/Edge/3G) 网络时限制,而当使用 WIFI 时不做任何限制。
  • 支持断点续传。
  • 支持同步和异步请求。

1.2 AFN 与 ASI 的区别

1、底层实现

1)AFN 的底层实现基于 OC 的 NSURLConnection 和 NSURLSession

2)ASI 的底层实现基于纯 C 语言的 CFNetwork 框架

3)因为 NSURLConnection 和 NSURLSession 是在 CFNetwork 之上的一层封装,因此 ASI 的运行性能高于 AFN

2、对服务器返回的数据处理

1)ASI 没有直接提供对服务器数据处理的方式,直接返回的是 NSData/NSString

2)AFN 提供了多种对服务器数据处理的方式 (1) JSON 处理-直接返回 NSDictionary 或者 NSArray

(2) XML 处理-返回的是 xml 类型数据,需对其进行解析

(3) 其他类型数据处理

3、监听请求过程 1

)AFN 提供了success 和 failure 两个 block 来监听请求的过程(只能监听成功和失败)

  • success : 请求成功后调用
  • failure : 请求失败后调用

2)ASI 提供了 3 套方案,每一套方案都能监听请求的完整过程(监听请求开始、接收到响应头信息、接受到具体数据、接受完毕、请求失败)

  • 成为代理,遵守协议,实现协议中的代理方法
  • 成为代理,不遵守协议,自定义代理方法
  • 设置 block

4、在文件下载和文件上传的使用难易度

1)AFN

  • 不容易实现监听下载进度和上传进度
  • 不容易实现断点续传
  • 一般只用来下载不大的文件

2)ASI

  • 非常容易实现下载和上传
  • 非常容易监听下载进度和上传进度
  • 非常容易实现断点续传
  • 下载大文件或小文件均可

3)实现下载上传推荐使用 ASI

5、网络监控

1)AFN 自己封装了网络监控类,易使用

2)ASI 使用的是 Reachability,因为使用 CocoaPods 下载 ASI 时,会同步下载 Reachability,但 Reachability 作为网络监控使用较为复杂(相对于 AFN 的网络监控类来说)

3)推荐使用 AFN 做网络监控 AFNetworkReachabilityManager

6、ASI 提供的其他实用功能

1)控制信号旁边的圈圈要不要在请求过程中转

2)可以轻松地设置请求之间的依赖:每一个请求都是一个 NSOperation 对象

3)可以统一管理所有请求(还专门提供了一个叫做 ASINetworkQueue 来管理所有的请求对象) 暂停/恢复/取消所有的请求
监听整个队列中所有请求的下载进度和上传进度

2、ASIHTTPRequest 的使用

2.1 添加 ASIHTTPRequest

Github 网址: https://github.com/pokeb/asi-http-request

https://allseeing-i.com/ASIHTTPRequest/

ASIHTTPRequest 系统需求:

ASIHTTPRequest Version Minimum iOS Target Target Notes
1.8.1 -> 1.8.2 iOS 3.0+
0.2 -> 1.8.0

ASIHTTPRequest 使用 MRC

Objective-C

  // 添加系统库文件
  CFNetwork.framework
  SystemConfiguration.framework
  MobileCoreServices.framework
  CoreGraphics.framework
  libz.1.1.3.tbd
  libxml2.2.tbd

  // 添加第三方库文件
  ASIHTTPRequest-1.8.2

  // 在 TARGETS -> Builed Settings -> Search Paths -> Header Search Paths 中添加文件路径
  /usr/include/libxml2

  // 在 TARGETS -> Build Phases -> Compile Sources -> ...in .../ASIHTTPRequest 后添加
  -fno-objc-arc

  // 包含头文件
  #import "ASIHTTPRequest.h"
  #import "ASIFormDataRequest.h"

2.2 ASIHTTPRequest 的设置

Objective-C

  // 设置请求头
  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://api.hudong.com/iphonexml.do?type=focus-c"]];
  [request addRequestHeader:@"Referer" value:@"http://www.dreamingwish.com/"];

  // 设置应用后台运行时是否仍然请求数据
  request.shouldContinueWhenAppEntersBackground = YES;

  // 设置请求超时时重试的次数
  request.numberOfTimesToRetryOnTimeout = 3;

  // 设置 KeepAlive 支持

    // Set the amount of time to hang on to a persistent connection before it should expire to 2 minutes
    request.persistentConnectionTimeoutSeconds = 120;

    // Disable persistent connections entirely
    request.shouldAttemptPersistentConnection = NO;

  // 设置是否显示网络请求信息在 status bar 上
  [ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:NO];

  // 网络状态检查
  BOOL isNetworkInUse = [ASIHTTPRequest isNetworkInUse];

3、ASI 同步 GET 请求

这是 ASIHTTPRequest 最简单的一种使用模式,发送 startSynchronous 消息后即开始在同一线程中执行 HTTP 请求,线程将一直等待直到请求结束(请求成功或者失败)。通过检查 error 属性可以判断请求是否成功或者有错误发生。

要获取返回的文本信息,调用 responseString 方法。如果下载的是二进制文件,例如图片、MP3,则调用 responseData 方法,可以得到一个 NSData 对象。

一般情况下,应该优先使用异步请求代替同步请求,当在主线程中使用 ASIHTTPRequest 同步请求会阻塞主线程的执行,这导致用户界面不响应用户操作,任何动画都会停止渲染,直到请求完成。

Objective-C

数据请求

  NSURL *url = [NSURL URLWithString:@"http://api.hudong.com/iphonexml.do?type=focus-c"];

  // 创建请求
  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

  // 设置超时时间,可不设置,使用默认
  request.timeOutSeconds = 5;

  // 发送同步请求
  [request startSynchronous];

  // 获得错误信息
  NSError *error = [request error];

  // 网络请求失败
  if (error) {

    // 网络请求成功
    NSLog(@"网络请求失败:\n%@", error);

  } else {

    // 获得服务器的响应,字符串格式
    NSString *responseString = [request responseString];
    NSLog(@"网络请求成功:\n%@", responseString);

    // 获得服务器的响应,NSData 格式
    NSData *responseData = [request responseData];
    textView.text = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
  }

文件下载

通过设置 request 的 setDownloadDestinationPath,可以设置下载文件用的下载目标目录。首先,下载过程文件会保存在 temporaryFileDownloadPath 目录下。如果下载完成会做以下事情:

1,如果数据是压缩的,进行解压,并把文件放在 downloadDestinationPath 目录中,临时文件被删除。

2,如果下载失败,临时文件被直接移到 downloadDestinationPath 目录,并替换同名文件。

如果你想获取下载中的所有数据,可以实现 delegate 中的 request:didReceiveData:方法。但如果你实现了这个方法,request 在下载完后,request 并不把文件放在 downloadDestinationPath中,需要手工处理。

  NSURL *url = [NSURL URLWithString:@"http://www.dreamingwish.com/wp-content/uploads/2011/10/asihttprequest-auth.png"];

  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

  // 设置文件存储路径
  [request setDownloadDestinationPath:@"/Users/JHQ0228/Desktop/asi.png"];

  [request startSynchronous];

  // 获得错误信息
  NSError *error = [request error];

  // 网络请求失败
  if (error) {

    NSLog(@"网络请求失败:\n%@", error);

  } else {

    // 网络请求成功
    NSLog(@"网络请求成功:\n");
  }

4、ASI 异步 GET 请求

请求在后台线程中运行,当请求执行完后再通知调用的线程。这样不会导致主线程进行网络请求时,界面被锁定等情况。

1、协议方式

在这里实现了两个 delegate 的方法,当数据请求成功时会调用 requestFinished,请求失败时(如网络问题或服务器内部错误)会调用 requestFailed。

  NSURL *url = [NSURL URLWithString:@"http://api.hudong.com/iphonexml.do?type=focus-c"];

  // 创建请求
  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

  // 设置超时时间,可不设置,使用默认
  request.timeOutSeconds = 5;

  // 设置代理,需遵守 <ASIHTTPRequestDelegate> 协议
  request.delegate = self;

  // 发送异步请求
  [request startAsynchronous];

  // 网络请求成功,协议方法
  - (void)requestFinished:(ASIHTTPRequest *)request {

  }

  // 网络请求失败,协议方法
  - (void)requestFailed:(ASIHTTPRequest *)request {

  }

2、Block 方式

在平台支持情况下,ASIHTTPRequest 1.8 以上支持 block。

  NSURL *url = [NSURL URLWithString:@"http://api.hudong.com/iphonexml.do?type=focus-c"];

  // 创建请求,加 __weak 除去 block 循环调用警告
  __weak ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

  // 设置超时时间,可不设置,使用默认
  request.timeOutSeconds = 5;

  // 发送异步请求
  [request startAsynchronous];

  // 网络请求成功
  [request setCompletionBlock:^{

  }];

  // 网络请求失败
  [request setFailedBlock:^{

  }];

5、ASI POST 请求

1、POST 表单

ASIFormDataRequest,模拟 Form 表单提交,其提交格式与 Header 会自动识别。文件中的数据是需要时才从磁盘加载,所以只要 web server 能处理,那么上传大文件是没有问题的。

  // 通常数据是以 'application/x-www-form-urlencoded' 格式发送的,如果上传了二进制数据或者文件,那么格式将自动变为 ‘multipart/form-data'。

    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://www.dreamingwish.com"]];

    // 没有文件
    [request setPostValue:@"Ben" forKey:@"first_name"];
    [request setPostValue:@"Copsey" forKey:@"last_name"];

    // 发送文件
    [request setFile:@"/Users/ben/Desktop/ben.jpg" forKey:@"photo"];

  // 数据的 mime 头是自动判定的,但是如果你想自定义mime头,那么这样:

    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://www.dreamingwish.com"]];

    // Upload a file on disk
    [request setFile:@"/Users/ben/Desktop/ben.jpg" withFileName:@"myphoto.jpg" andContentType:@"image/jpeg" forKey:@"photo"]; 

    // Upload an NSData instance
    NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed:@"myphoto.jpg"]);
    [request setData:imageData withFileName:@"myphoto.jpg" andContentType:@"image/jpeg" forKey:@"photo"];

  // 你可以使用 addPostValue 方法来发送相同 name 的多个数据:

    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://www.dreamingwish.com"]];

    [request addPostValue:@"Ben" forKey:@"names"];
    [request addPostValue:@"George" forKey:@"names"];

2、PUT 请求、自定义 POST 请求

如果你想发送 PUT 请求,或者你想自定义 POST 请求,使用 appendPostData: 或者 appendPostDataFromFile:

  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://www.dreamingwish.com"]];

  [request appendPostData:[@"This is my data" dataUsingEncoding:NSUTF8StringEncoding]];

  // Default becomes POST when you use appendPostData: / appendPostDataFromFile: / setPostBody:
  [request setRequestMethod:@"PUT"];

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解iOS通过ASIHTTPRequest提交JSON数据

    先验知识--什么是ASIHTTPRequest? 使用iOS SDK中的HTTP网络请求API,相当的复杂,调用很繁琐,ASIHTTPRequest就是一个对CFNetwork API进行了封装,并且使用起来非常简单的一套API,用Objective-C编写,可以很好的应用在Mac OS X系统和iOS平台的应用程序中.ASIHTTPRequest适用于基本的HTTP请求,和基于REST的服务之间的交互. 上传JSON格式数据 首先给出主功能代码段,然后对代码进行详细解析: NSDictiona

  • 详解iOS - ASIHTTPRequest 网络请求

    前言 使用 iOS SDK 中的 HTTP 网络请求 API,相当的复杂,调用很繁琐,ASIHTTPRequest 就是一个对 CFNetwork API 进行了封装,并且使用起来非常简单的一套 API,外号 "HTTP终结者",用 Objective-C 编写,运行效率很高,可以很好的应用在 Mac OS X 系统和 iOS 平台的应用程序中,ASIHTTPRequest 适用于基本的 HTTP 请求,和基于 REST 的服务之间的交互.可惜作者早已停止更新,有一些潜在的 BUG 无

  • 详解React Native网络请求fetch简单封装

    在原生应用开发中,为了方便业务开发人员使用,我们一般会对网络库进行一些上传封装,而不是直接使用,例如基于AFNetworking库的iOS请求上层封装,Android的诸如volley,retrofit等.在前端开发中,一般使用fetch进行网络请求,相关介绍请查看fetch示例.其实对于开发来说,系统提供的fetch已经够用了,但是为了代码的整体结构,建议对fetch进行简单的Get/Post封装. 若不封装,我们看一下传统的写法: fetch('http://www.pintasty.cn/

  • 详解flutter之网络请求dio,请求,拦截器简单示例

    flutter一直很火的网络请求插件dio 直接上代码,写成一个类,可以直接使用 包含请求的封装,拦截器的封装 import 'package:dio/dio.dart'; import 'dart:async'; import 'dart:io'; import './apidomain.dart'; import './httpHeaders.dart'; import 'package:shared_preferences/shared_preferences.dart'; class D

  • 详解IOS判断当前网络状态的三种方法

    在项目中,为了好的用户体验,有些场景必须线判断网络状态,然后才能决定该干嘛.比如视频播放,需要线判断是Wifi还是4G,Wifi直接播放,4G先提示用户.获取网络状态的方法大概有三种: 1. Reachability 这是苹果的官方演示demo中使用到的方法,我们可以到苹果官方文档里下载Demo(点击左上角Download Sample Code 即可下载),然后把Demo里的Reachability.h和.m考到自己项目中,并在Build Phases 的 Link Binary 添加Syst

  • 详解IOS WebRTC的实现原理

    概述 它在2011年5月开放了工程的源代码,在行业内得到了广泛的支持和应用,成为下一代视频通话的标准. WebRTC的音视频通信是基于P2P,那么什么是P2P呢? 它是点对点连接的英文缩写. P2P连接模式 一般我们传统的连接方式,都是以服务器为中介的模式: 类似http协议:客户端?服务端(当然这里服务端返回的箭头仅仅代表返回请求数据). 我们在进行即时通讯时,进行文字.图片.录音等传输的时候:客户端A?服务器?客户端B. 而点对点的连接恰恰数据通道一旦形成,中间是不经过服务端的,数据直接从一

  • 详解IOS如何防止抓包

    目录 抓包原理 防止抓包 一.发起请求之前判断是否存在代理,存在代理就直接返回,请求失败. 二.我们可以在请求配置中清空代理,让请求不走代理 SSL Pinning(AFN+SSL Pinning)推荐 扩展 抓包原理 其实原理很是简单:一般抓包都是通过代理服务来冒充你的服务器,客户端真正交互的是这个假冒的代理服务,这个假冒的服务再和我们真正的服务交互,这个代理就是一个中间者 ,我们所有的数据都会通过这个中间者,所以我们的数据就会被抓取.HTTPS 也同样会被这个中间者伪造的证书来获取我们加密的

  • 详解Flutter中网络框架dio的二次封装

    其实dio框架已经封装的很好了,但是在实战项目中,为了项目可以统一管理,还是需要对dio框架进行二次封装. 整体思路:一般情况下,后台返回的数据我们可以分为两部分 1.状态数据 2.渲染数据 状态数据就是接口有没有正常返回数据相关的数据,这部分数据跟业务无关,我们可以封装起来统一管理,渲染数据就是我们渲染页面所需要的数据,这块的数据需要我们自己处理. 接下来我们就主要处理渲染数据这块的内容,我定义了两个函数,渲染数据可能为一个对象或者一个数组,我做了分别处理,定义两个函数来接受渲染数据. //

  • 详解IOS UITableViewCell 的 imageView大小更改

    详解IOS UITableViewCell 的 imageView大小更改 实例代码: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCell

  • 详解IOS开发中生成推送的pem文件

    详解IOS开发中生成推送的pem文件 具体步骤如下: 首先,需要一个pem的证书,该证书需要与开发时签名用的一致. 具体生成pem证书方法如下: 1. 登录到 iPhone Developer Connection Portal(http://developer.apple.com/iphone/manage/overview/index.action )并点击 App IDs 2. 创建一个不使用通配符的 App ID .通配符 ID 不能用于推送通知服务.例如,  com.itotem.ip

  • iOS判断网络请求超时的方法

    本文介绍了iOS判断网络请求超时的方法,代码具体如下: + (AFHTTPRequestOperation *)requestOperationWithUrl:(NSString *)url requetMethod:(NSString *)method paramData:(NSDictionary *)aParamData constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block success

随机推荐