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 。欢迎大家访问!
- iOS开发——网络请求案例汇总
- iOS开发——网络请求案例汇总(AFNetworking)
- iOS开发——网络请求数据处理
- iOS开发网络篇—GET请求和POST请求
- iOS开发网络篇—GET请求和POST请求
- IOS开发—网络请求之GET/POST同步请求
- IOS开发—网络请求之代理异步请求
- iOS开发网络篇—GET请求和POST请求
- iOS开发网络篇—GET请求和POST请求
- iOS开发网络—04GET请求和POST请求
- iOS开发网络篇—GET请求和POST请求
- iOS开发网络篇—GET请求和POST请求
- iOS开发网络篇—GET请求和POST请求
- iOS开发网络篇—GET请求和POST请求
- iOS开发网络篇—GET请求和POST请求
- iOS开发网络篇—GET请求和POST请求
- iOS开发网络篇—GET请求和POST请求
- iOS开发网络篇—GET请求和POST请求
- Android开发总结笔记 SearchView&Search(搜索相关) 1-3-7
- 3张图解决 Windows cmd dos 乱码问题
- 折腾:瀑布流布局(基于多栏列表流体布局实现)
- C++primer plus第六版课后编程练习答案5.4
- iOS屏幕旋转问题
- iOS开发——网络请求案例汇总
- 安装jad仍不能反编译的问题
- 自学C++可行性研究
- Bootstrap tabs选项卡实现
- android删除未使用的资源文件
- 关于sql
- poj 1388 Hinge Node Problem floyd算法的扩展运用
- 表单包含file上传文件提交,使用ajaxSubmint或者ajaxForm 遇到的问题以及解决方法
- 如何修改iOS APP的项目名称