iOS开发——网络请求案例汇总

来源:互联网 发布:网络叫萝卜什么意思啊 编辑:程序博客网 时间:2024/05/29 17:29

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

【1.使用XML请求SOAP,用NSURLConnectionDelegate实现】

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

实现代码如下:

#import "SOAP1ViewController.h"@interface SOAP1ViewController ()<NSURLConnectionDelegate>@property (strong, nonatomic) NSMutableData *webData;@property (strong, nonatomic) NSURLConnection *conn;@end@implementation SOAP1ViewController- (void)viewDidLoad {  [super viewDidLoad];    [self query:@"18888888888"];  }-(void)query:(NSString*)phoneNumber{    // 创建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, @""];    NSURL *url = [NSURL URLWithString: @"http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx"];  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"];  [req setHTTPMethod:@"POST"];  [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

打印结果如下:



【2.使用XML请求SOAP,用NSURLConnection实现

使用上述1的方法显得代码有点多,我们可以用最简单的NSURLConnection来实现,虽然现在已经不推荐使用NSURLConnection。但是我们还是来实现一下。这里采用异步请求的方式实现,就不会阻塞主线程。实现代码如下:

#import "SOAP2ViewController.h"@interface SOAP2ViewController ()@property (strong, nonatomic) NSMutableData *webData;@property (strong, nonatomic) NSURLConnection *conn;@end@implementation SOAP2ViewController- (void)viewDidLoad {    [super viewDidLoad];  [self query:@"18888888888"];  }-(void)query:(NSString*)phoneNumber{    // 设置我们之后解析XML时用的关键字,与响应报文中Body标签之间的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]];  // 创建连接          [NSURLConnection sendAsynchronousRequest:req queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {        if (!connectionError) {          NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];          NSLog(@"成功:%@",result);      }else{          NSLog(@"失败:%@",connectionError);      }      }];  }@end
打印结果与上述1一样。


【3.使用XML请求SOAP,用NSURLSession实现

目前苹果已经强烈推荐使用NSURLSession来进行网络请求了,虽然实现的代码量和难度 与NSURLConnection也差不多。实现代码如下:

#import "SOAP3ViewController.h"@interface SOAP3ViewController ()@property (strong, nonatomic) NSMutableData *webData;@property (strong, nonatomic) NSURLConnection *conn;@end@implementation SOAP3ViewController- (void)viewDidLoad {    [super viewDidLoad];  [self query:@"18888888888"];  }-(void)query:(NSString*)phoneNumber{    // 设置我们之后解析XML时用的关键字,与响应报文中Body标签之间的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]];  // 创建连接    NSURLSession *session = [NSURLSession sharedSession];  NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {        if (!error) {            NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];            NSLog(@"成功:%@",result);    }else{            NSLog(@"失败 : %@",error);    }              }];    [dataTask resume];  }@end
打印结果与1相同。

【4.普通的Http请求,使用NSURLConnection】

最基本最普通的网络请求就是发送一个链接,链接里包含了需要发送的参数,同时请求方式可以是GET或者POST。这里我也是使用http://www.webxml.com.cn/zh_cn/web_services.aspx 进行号码归属地的请求。实现代码如下:

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

打印结果如下:



【5.普通的Http请求,使用NSURL Session】

NSURLSession是对NSURLConnection的改进与优化。这是对4的改进。实现代码如下:

#import "HttpGet2ViewController.h"@interface HttpGet2ViewController ()@end@implementation HttpGet2ViewController- (void)viewDidLoad {    [super viewDidLoad];  /*   为什么要执行如下方法?   因为有的服务端要求把中文进行utf8编码,而我们的代码默认是unicode编码。必须要进行一下的转码,否则返回的可能为空,或者是其他编码格式的乱码了!   注意可以对整个url直接进行转码,而没必要对出现的每一个中文字符进行编码;   */      //以下方法已经不推荐使用;  //  NSString *urlStr = [@"http://v.juhe.cn/weather/index?format=2&cityname=北京&key=88e194ce72b455563c3bed01d5f967c5"stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];      //建议使用这个方法stringByAddingPercentEncodingWithAllowedCharacters,不推荐使用stringByAddingPercentEscapesUsingEncoding;  NSString *urlStr2 = [@"http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo?mobileCode=18888888888&userId=" stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];  [self asynHttpGet:urlStr2];  }- (NSString *)asynHttpGet:(NSString *)urlAsString{  NSURL *url = [NSURL URLWithString:urlAsString];  //  __block NSString *resault=@"";  NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];  [urlRequest setTimeoutInterval:30];  [urlRequest setHTTPMethod:@"GET"];      //推荐使用这种请求方法;  NSURLSession *session = [NSURLSession sharedSession];    __block  NSString *result = @"";  NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:urlRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {        if (!error) {      //没有错误,返回正确;      result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];      NSLog(@"返回正确:%@",result);          }else{      //出现错误;      NSLog(@"错误信息:%@",error);    }      }];      [dataTask resume];      return result;    }@end

打印结果与4一样。






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



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

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



1 0
原创粉丝点击