iOS开发——网络请求方法汇总

在实际的项目开发中,连接网络是每一款App必不可少的基本功能。对于客户端的网络请求而言,无非是有两个实现方向:使用网络请求框架或者不使用网络请求框架。在这篇博客中,我将用苹果自带的网络请求方式(不使用第三方框架)下对iOS网络请求方法做一个汇总。我将在之后的博客中介绍使用AFNetworking框架进行请求的实现。代码已经上传至:https://github.com/chenyufeng1991/iOS-NetworkRequest
  。

【使用XML请求Webservice,可用GET或POST】

很多网络数据是通过WebService请求的,http://www.webxml.com.cn/zh_cn/web_services.aspx 。上面有很多不错的接口,我们需要使用WebService发送XML的方式来实现。我这里来调用手机号码归属地的接口,并OC实现,使用的是苹果自带的NSURLConnectionDelegate。请注意,有的WebService支持GET,有的支持POST,有的两者都支持。这个就要看服务端了。大家可以分别来进行测试。在该示例中,不支持GET方式,所以我就是用了POST。

实现代码如下:

#import "WebServiceViewController.h"

@interface WebServiceViewController ()<NSURLConnectionDelegate>

@property (strong, nonatomic) NSMutableData *webData;
@property (strong, nonatomic) NSMutableString *soapResults;
@property (strong, nonatomic) NSXMLParser *xmlParser;
@property (nonatomic) BOOL elementFound;
@property (strong, nonatomic) NSString *matchingElement;
@property (strong, nonatomic) NSURLConnection *conn;

@property (strong,nonatomic) NSString *xmlReturnToMainThread;

@end

@implementation WebServiceViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  [self query:@"18888888888"];

}

-(void)query:(NSString*)phoneNumber{

  // 设置我们之后解析XML时用的关键字,与响应报文中Body标签之间的getMobileCodeInfoResult标签对应
  self.matchingElement = @"getMobileCodeInfoResult";
  // 创建SOAP消息,内容格式就是网站上提示的请求报文的主体实体部分    这里使用了SOAP1.2;
  NSString *soapMsg = [NSString stringWithFormat:
                       @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                       "<soap12:Envelope "
                       "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
                       "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
                       "xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">"
                       "<soap12:Body>"
                       "<getMobileCodeInfo xmlns=\"http://WebXml.com.cn/\">"
                       "<mobileCode>%@</mobileCode>"
                       "<userID>%@</userID>"
                       "</getMobileCodeInfo>"
                       "</soap12:Body>"
                       "</soap12:Envelope>", phoneNumber, @""];

  // 将这个XML字符串打印出来
//  NSLog(@"%@", soapMsg);
  // 创建URL,内容是前面的请求报文报文中第二行主机地址加上第一行URL字段
  NSURL *url = [NSURL URLWithString: @"http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx"];
  // 根据上面的URL创建一个请求
  NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
  NSString *msgLength = [NSString stringWithFormat:@"%lu", (unsigned long)[soapMsg length]];
  // 添加请求的详细信息,与请求报文前半部分的各字段对应
  [req addValue:@"application/soap+xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
  [req addValue:msgLength forHTTPHeaderField:@"Content-Length"];
  // 设置请求行方法为POST,与请求报文第一行对应
  [req setHTTPMethod:@"POST"];
  // 将SOAP消息加到请求中
  [req setHTTPBody: [soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
  // 创建连接
  self.conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
  if (self.conn) {
    self.webData = [NSMutableData data];
  }

}

// 刚开始接受响应时调用
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *) response{
  [self.webData setLength: 0];
}

// 每接收到一部分数据就追加到webData中
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *) data {

  if(data != NULL){
    [self.webData appendData:data];
  }

}

// 出现错误时
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *) error {
  self.conn = nil;
  self.webData = nil;
}

// 完成接收数据时调用
-(void) connectionDidFinishLoading:(NSURLConnection *) connection {
  NSString *theXML = [[NSString alloc] initWithBytes:[self.webData mutableBytes]
                                              length:[self.webData length]
                                            encoding:NSUTF8StringEncoding];

  // 打印出得到的XML
  NSLog(@"返回的数据:%@", theXML);

}

@end

打印结果如下:

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/"><getMobileCodeInfoResult>18888888888:北京 北京 北京移动全球通卡</getMobileCodeInfoResult></getMobileCodeInfoResponse></soap:Body></soap:Envelope>

【Http GET请求】

其实总的来说,第一个例子中的WebService请求也算是Http请求的一种,只是发送的格式是XML类型,而一般来说,进行get请求都可以单纯发送一个链接即可。这里我将使用聚合数据的接口,来请求天气数据:https://www.juhe.cn/docs/api/id/39。使用异步请求。同第一个示例的不同是这里发送的不是XML格式。

注意这里代码中有非常重要的一个步骤就是就是转码,服务器一般接受的是utf8的编码,否则可能会返回乱码。在该接口中,服务器支持GET请求和POST请求,所以如果你想进行的是POST请求,可以直接把代码中的GET改成POST(虽然这种POST方式不是特别规范,因为最好POST的时候不要把参数放到链接中)。实现代码如下:

<p class="p1"><span class="s1">#import </span><span class="s2">"HttpGetViewController.h"</span></p><p class="p2"><span class="s2"></span>
</p><p class="p3"><span class="s3">@interface</span><span class="s4"> </span><span class="s2">HttpGetViewController</span><span class="s4"> ()</span></p><p class="p2"><span class="s2"></span>
</p><p class="p4"><span class="s2">@end</span></p><p class="p2"><span class="s2"></span>
</p><p class="p5"><span class="s3">@implementation</span><span class="s2"> HttpGetViewController</span></p><p class="p2"><span class="s2"></span>
</p><p class="p5"><span class="s2">- (</span><span class="s3">void</span><span class="s2">)viewDidLoad {</span></p><p class="p6"><span class="s4">  [</span><span class="s3">super</span><span class="s4"> </span><span class="s2">viewDidLoad</span><span class="s4">];</span></p><p class="p2"><span class="s2">  </span></p><p class="p7"><span class="s4">  </span><span class="s2">/*</span></p><p class="p8"><span class="s5">   </span><span class="s2">为什么要执行如下方法?</span></p><p class="p8"><span class="s5">   </span><span class="s2">因为有的服务端要求把中文进行</span><span class="s5">utf8</span><span class="s2">编码,而我们的代码默认是</span><span class="s5">unicode</span><span class="s2">编码。必须要进行一下的转码,否则返回的可能为空,或者是其他编码格式的乱码了!</span></p><p class="p8"><span class="s5">   </span><span class="s2">注意可以对整个</span><span class="s5">url</span><span class="s2">直接进行转码,而没必要对出现的每一个中文字符进行编码;</span></p><p class="p7"><span class="s2">   */</span></p><p class="p2"><span class="s2">  </span></p><p class="p2"><span class="s2">  </span></p><p class="p8"><span class="s6">  </span><span class="s5">//</span><span class="s2">以下方法已经不推荐使用;</span></p><p class="p7"><span class="s4">  </span><span class="s2">//  NSString *urlStr = [@"<a target=_blank href="http://v.juhe.cn/weather/index?format=2&cityname="><span class="s7">http://v.juhe.cn/weather/index?format=2&cityname=</span></a></span><span class="s8">北京</span><span class="s2">&key=88e194ce72b455563c3bed01d5f967c5"stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];</span></p><p class="p2"><span class="s2">  </span></p><p class="p7"><span class="s4">  </span><span class="s2">//</span><span class="s8">建议使用这个方法</span><span class="s2">stringByAddingPercentEncodingWithAllowedCharacters</span><span class="s8">,不推荐使用</span><span class="s2">stringByAddingPercentEscapesUsingEncoding</span><span class="s8">;</span></p><p class="p6"><span class="s4">  </span><span class="s2">NSString</span><span class="s4"> *urlStr2 = [</span><span class="s9">@"http://v.juhe.cn/weather/index?format=2&cityname=</span><span class="s10">北京</span><span class="s9">&key=88e194ce72b455563c3bed01d5f967c5"</span><span class="s4"> </span><span class="s2">stringByAddingPercentEncodingWithAllowedCharacters</span><span class="s4">:[</span><span class="s2">NSCharacterSet</span><span class="s4"> </span><span class="s2">URLQueryAllowedCharacterSet</span><span class="s4">]];</span></p><p class="p5"><span class="s2">  [</span><span class="s3">self</span><span class="s2"> </span><span class="s11">asynHttpGet</span><span class="s2">:urlStr2];</span></p><p class="p2"><span class="s2">  </span></p><p class="p2"><span class="s2">  </span></p><p class="p2"><span class="s2">  </span></p><p class="p5"><span class="s2">}</span></p><p class="p2"><span class="s2"></span>
</p><p class="p5"><span class="s2">- (</span><span class="s12">NSString</span><span class="s2"> *)asynHttpGet:(</span><span class="s12">NSString</span><span class="s2"> *)urlAsString{</span></p><p class="p5"><span class="s2">  </span><span class="s12">NSURL</span><span class="s2"> *url = [</span><span class="s12">NSURL</span><span class="s2"> </span><span class="s12">URLWithString</span><span class="s2">:urlAsString];</span></p><p class="p5"><span class="s2">  </span><span class="s3">__block</span><span class="s2"> </span><span class="s12">NSString</span><span class="s2"> *resault=</span><span class="s9">@""</span><span class="s2">;</span></p><p class="p6"><span class="s4">  </span><span class="s2">NSMutableURLRequest</span><span class="s4"> *urlRequest = [</span><span class="s2">NSMutableURLRequest</span><span class="s4"> </span><span class="s2">requestWithURL</span><span class="s4">:url];</span></p><p class="p6"><span class="s4">  [urlRequest </span><span class="s2">setTimeoutInterval</span><span class="s4">:</span><span class="s13">30</span><span class="s4">];</span></p><p class="p5"><span class="s2">  [urlRequest </span><span class="s12">setHTTPMethod</span><span class="s2">:</span><span class="s9">@"GET"</span><span class="s2">];</span></p><p class="p2"><span class="s2">  </span></p><p class="p6"><span class="s4">  </span><span class="s2">NSOperationQueue</span><span class="s4"> *queue = [[</span><span class="s2">NSOperationQueue</span><span class="s4"> </span><span class="s2">alloc</span><span class="s4">] </span><span class="s2">init</span><span class="s4">];</span></p><p class="p2"><span class="s2">  </span></p><p class="p6"><span class="s4">  [</span><span class="s2">NSURLConnection</span></p><p class="p6"><span class="s4">   </span><span class="s2">sendAsynchronousRequest</span><span class="s4">:urlRequest</span></p><p class="p5"><span class="s2">   </span><span class="s12">queue</span><span class="s2">:queue</span></p><p class="p6"><span class="s4">   </span><span class="s2">completionHandler</span><span class="s4">:^(</span><span class="s2">NSURLResponse</span><span class="s4"> *response,</span></p><p class="p5"><span class="s2">                       </span><span class="s12">NSData</span><span class="s2"> *data,</span></p><p class="p5"><span class="s2">                       </span><span class="s12">NSError</span><span class="s2"> *error) {</span></p><p class="p2"><span class="s2">     </span></p><p class="p5"><span class="s2">     </span><span class="s3">if</span><span class="s2"> ([data </span><span class="s12">length</span><span class="s2">] ></span><span class="s13">0</span><span class="s2">  &&</span></p><p class="p5"><span class="s2">         error == </span><span class="s3">nil</span><span class="s2">){</span></p><p class="p6"><span class="s4">       </span><span class="s2">NSString</span><span class="s4"> *html = [[</span><span class="s2">NSString</span><span class="s4"> </span><span class="s2">alloc</span><span class="s4">] </span><span class="s2">initWithData</span><span class="s4">:data</span></p><p class="p5"><span class="s2">                                              </span><span class="s12">encoding</span><span class="s2">:</span><span class="s12">NSUTF8StringEncoding</span><span class="s2">];</span></p><p class="p5"><span class="s2">       resault=[html </span><span class="s12">copy</span><span class="s2">];</span></p><p class="p2"><span class="s2">       </span></p><p class="p5"><span class="s2">       </span><span class="s12">NSLog</span><span class="s2">(</span><span class="s9">@"</span><span class="s10">返回的服务器数据</span><span class="s9"> = %@"</span><span class="s2">, html);</span></p><p class="p5"><span class="s2">     }</span></p><p class="p5"><span class="s2">     </span><span class="s3">else</span><span class="s2"> </span><span class="s3">if</span><span class="s2"> ([data </span><span class="s12">length</span><span class="s2">] == </span><span class="s13">0</span><span class="s2"> &&</span></p><p class="p5"><span class="s2">              error == </span><span class="s3">nil</span><span class="s2">){</span></p><p class="p1"><span class="s4">       resault=</span><span class="s2">@"Nothing was downloaded."</span><span class="s4">;</span></p><p class="p1"><span class="s4">       </span><span class="s12">NSLog</span><span class="s4">(</span><span class="s2">@"Nothing was downloaded."</span><span class="s4">);</span></p><p class="p5"><span class="s2">     }</span></p><p class="p5"><span class="s2">     </span><span class="s3">else</span><span class="s2"> </span><span class="s3">if</span><span class="s2"> (error != </span><span class="s3">nil</span><span class="s2">){</span></p><p class="p5"><span class="s2">       resault=[</span><span class="s12">NSString</span><span class="s2"> </span><span class="s12">stringWithFormat</span><span class="s2">:</span><span class="s9">@"Error happened = %@"</span><span class="s2">, error];</span></p><p class="p5"><span class="s2">       </span><span class="s12">NSLog</span><span class="s2">(</span><span class="s9">@"</span><span class="s10">发生错误</span><span class="s9"> = %@"</span><span class="s2">, error);</span></p><p class="p5"><span class="s2">     }</span></p><p class="p2"><span class="s2">     </span></p><p class="p5"><span class="s2">   }];</span></p><p class="p5"><span class="s2">  </span><span class="s3">return</span><span class="s2"> resault;</span></p><p class="p2"><span class="s2">  </span></p><p class="p2"><span class="s2">  </span></p><p class="p5"><span class="s2">}</span></p><p class="p2"><span class="s2"></span>
</p><p class="p4"><span class="s2">@end</span></p>

打印结果如下:

{"resultcode":"200","reason":"successed!","result":{"sk":{"temp":"-2","wind_direction":"西南风","wind_strength":"3级","humidity":"40%","time":"16:56"},"today":{"temperature":"-8℃~0℃","weather":"晴转多云","weather_id":{"fa":"00","fb":"01"},"wind":"北风3-4 级","week":"星期四","city":"北京","date_y":"2015年11月26日","dressing_index":"冷","dressing_advice":"天气冷,建议着棉服、羽绒服、皮夹克加羊毛衫等冬季服装。年老体弱者宜着厚棉衣、冬大衣或厚羽绒服。","uv_index":"弱","comfort_index":"","wash_index":"较适宜","travel_index":"较不宜","exercise_index":"较不宜","drying_index":""},"future":[{"temperature":"-8℃~0℃","weather":"晴转多云","weather_id":{"fa":"00","fb":"01"},"wind":"北风3-4 级","week":"星期四","date":"20151126"},{"temperature":"-6℃~1℃","weather":"多云转晴","weather_id":{"fa":"01","fb":"00"},"wind":"微风","week":"星期五","date":"20151127"},{"temperature":"-5℃~3℃","weather":"晴转多云","weather_id":{"fa":"00","fb":"01"},"wind":"微风","week":"星期六","date":"20151128"},{"temperature":"-5℃~5℃","weather":"多云转晴","weather_id":{"fa":"01","fb":"00"},"wind":"微风","week":"星期日","date":"20151129"},{"temperature":"-3℃~5℃","weather":"晴转阴","weather_id":{"fa":"00","fb":"02"},"wind":"微风","week":"星期一","date":"20151130"},{"temperature":"-3℃~3℃","weather":"阴转多云","weather_id":{"fa":"02","fb":"01"},"wind":"微风","week":"星期二","date":"20151201"},{"temperature":"-3℃~5℃","weather":"多云转晴","weather_id":{"fa":"01","fb":"00"},"wind":"微风","week":"星期三","date":"20151202"}]},"error_code":0}

总结,网络请求虽然代码看起来有点多,但还是比较简单的,也基本上是固定的,可以直接拿过来用。我将在下一篇博客中介绍使用AFNetworking来进行请求。

最近开源的iOS应用,高仿印象笔记  https://github.com/chenyufeng1991/iOS-Oncenote 。欢迎大家点赞并关注项目进度。也可以安装到手机上试玩哦。

github主页:https://github.com/chenyufeng1991  。欢迎大家访问!

时间: 2024-12-23 02:08:22

iOS开发——网络请求方法汇总的相关文章

iOS开发网络请求——大文件的多线程断点下载

iOS开发中网络请求技术已经是移动app必备技术,而网络中文件传输就是其中重点了.网络文件传输对移动客户端而言主要分为文件的上传和下载.作为开发者从技术角度会将文件分为小文件和大文件.小文件因为文件大小比较小导致传输所需时间少传输就快,因此不太容易影响用户体验,可用的技术就多.而大文件因为文件大小比较大导致传输时间长,因此就需要考虑到各种用户体验,比如避免在上传下载文件过程中阻塞主线程影响用户体验,就需要使用到多线程技术:为了给用户友好的进度提示,因此又需要开发中跟踪数据上传和下载数据的变化:为

iOS开发网络篇—发送GET和POST请求(使用NSURLSession)

iOS开发网络篇—发送GET和POST请求(使用NSURLSession) 说明: 1)该文主要介绍如何使用NSURLSession来发送GET请求和POST请求 2)本文将不再讲解NSURLConnection的使用,如有需要了解NSURLConnection如何发送请求. 详细信息,请参考:http://www.cnblogs.com/wendingding/p/3813706.html 3)本文示例代码发送的请求均为http请求,已经对info.plist文件进行配置. 如何配置,请参考:

iOS开发网络篇—GET请求和POST请求

iOS开发网络篇—GET请求和POST请求 一.GET请求和POST请求简单说明 创建GET请求 1 // 1.设置请求路径 2 NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text]; 3 NSURL *url=[NSURL URLWithString:u

iOS开发网络数据之AFNetworking使用

iOS开发网络数据之AFNetworking使用 如何选择AFNetworking版本 首先得下载AFNetworking库文件,下载时得首先弄清楚,你将要开发的软件兼容的最低版本是多少.AFNetworking 2.0或者之后的版本需要xcode5.0版本并且只能为IOS6或更高的手机系统上运行,如果开发MAC程序,那么2.0版本只能在MAC OS X 10.8或者更高的版本上运行. AFNetworking 2.0的下载地址https://github.com/AFNetworking/AF

iOS开发网络篇—大文件的多线程断点下载(转)

http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始,创建一个和要下载的文件大小相同的文件(如果要下载的文件为100M,那么就在沙盒中创建一个100M的文件,然后计算每一段的下载量,开启多条线程下载各段的数据,分别写入对应的文件部分). 项目中用到的主要

iOS开发网络篇—NSURLConnection基本使用

iOS开发网络篇—NSURLConnection基本使用 一.NSURLConnection的常用类 (1)NSURL:请求地址 (2)NSURLRequest:封装一个请求,保存发给服务器的全部数据,包括一个NSURL对象,请求方法.请求头.请求体.... (3)NSMutableURLRequest:NSURLRequest的子类 (4)NSURLConnection:负责发送请求,建立客户端和服务器的连接.发送NSURLRequest的数据给服务器,并收集来自服务器的响应数据 二.NSUR

iOS开发网络篇—简单介绍ASI框架的使用

iOS开发网络篇—简单介绍ASI框架的使用 说明:本文主要介绍网络编程中常用框架ASI的简单使用. 一.ASI简单介绍 ASI:全称是ASIHTTPRequest,外号“HTTP终结者”,功能十分强大. ASI的实现基于底层的CFNetwork框架,因此运行效率很高.可惜作者早已停止更新,有一些潜在的BUG无人去解决 ASI的github地址 https://github.com/pokeb/asi-http-request ASI的使用参考 http://www.cnblogs.com/dot

iOS开发网络篇—多线程断点下载

iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始,创建一个和要下载的文件大小相同的文件(如果要下载的文件为100M,那么就在沙盒中创建一个100M的文件,然后计算每一段的下载量,开启多条线程下载各段的数据,分别写入对应的文件部分). 项目中用到的主要类如下: 完成的实现代码如下: 主控制器中的代码: 1 #import "YYViewControl

IOS开发网络篇之──ASIHTTPRequest下载示例(支持断点续传)

IOS开发网络篇之──ASIHTTPRequest下载示例(支持断点续传) 网络ios文件管理器attributespathurl 在工程中,我们会常常遇到需要下载的程序,比如下载在线音乐.下载图片等等,今天我将介绍一下利用ASIHTTPRequest的下载示例,支持断点续传,利用ASIHTTPRequest下载以及断点续传的原理在我的博客:http://blog.csdn.net/pjk1129/article/details/6575588中有具体的介绍,今天重点介绍如何实现,废话少说,开始