SOAP是简单对象访问协议,它可看成是HTTP与XML的结合,其中XML部分是作为HTTP报文的实体主体部分。
SOAP:简单对象访问协议,是一种轻量的、简单的、基于 XML 的协议,它被设计成在 WEB 上交换结构化的和固化的信息。 SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议( HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还支持从消息系统到远程过程调用(RPC)等大量的应用程序。
下面重点说下:
在iOS中使用SOAP,需要我们自己组装XML格式的字符串,当XML字符串比较长的时候会变得很麻烦。另外,我们在写XML格式的字符串时也要经常使用转义字符“\”。
若在mobileCode输入手机号码,userID不输入,点击调用,则结果如下:
看看刚才那个网页的内容,注意到SOAP 1.2标签下的内容:
上面的这段文本就是使用SOAP 1.2的请求报文格式,就是一个HTTP请求报文,注意空行上面的那些内容中的请求行与各首部行的每个字段名,在下面的示例中会用到。这个HTTP请求报文的实体主体部分是XML格式的一段文本,注意Body标签之间的内容。
服务器的响应报文格式如下:
我们要用到的只有getMobileCodeInfoResult这个标签。
这次的例子是实现通过SOAP服务查询手机号码归属地、运行商等信息。PS:用的Xcode 4.4.1。
1、运行Xcode 4.4.1,新建一个Single View Application,名称为SOAP Test:
2、界面设计:打开ViewController.xib,设计界面如下所示:
在文本输入框的Attribute Inspector中设置其Keyboard属性为Number Pad。
3、之后向ViewController.h中,为文本输入框创建OutLet映射,名称为:phoneNumber;为“查询”按钮创建Action映射,事件类型为Touch Up Inside,名称为:doQuery。建立映射的方法就是打开Assistant Editor,选中某一控件,按住Ctrl,拖向ViewController.h。
4、在ViewController.h中添加代码:
4.1 在@interface那行最后添加代码
使ViewController遵守这两个协议。前者用来解析XML,后者用于网络连接。
4.2 在@end之前添加代码@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;
5、在ViewController.m中添加代码:
5.1 在@implementation之后添加代码@synthesizewebData;@synthesizesoapResults;@synthesizexmlParser;@synthesizeelementFound;@synthesizematchingElement;@synthesizeconn;
5.2 实现doQuery方法
5.3 在@end之前添加代码#pragmamark-#pragmamark URLConnectionDataDelegateMethods// 刚开始接受响应时调用-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response{[webData setLength:0];}// 每接收到一部分数据就追加到webData中-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data{[webData appendData:data];}// 出现错误时-(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error{conn=nil;webData=nil;}// 完成接收数据时调用-(void)connectionDidFinishLoading:(NSURLConnection*)connection{NSString*theXML=[[NSStringalloc]initWithBytes:[webData mutableBytes]length:[webData length]encoding:NSUTF8StringEncoding];// 打印出得到的XMLNSLog(@"%@",theXML);// 使用NSXMLParser解析出我们想要的结果xmlParser=[[NSXMLParseralloc]initWithData:webData];[xmlParser setDelegate:self];[xmlParser setShouldResolveExternalEntities:YES];[xmlParser parse];}
5.4 在@end之前添加代码#pragmamark-#pragmamark XMLParserDelegateMethods// 开始解析一个元素名-(void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qName attributes:(NSDictionary*)attributeDict{if([elementName isEqualToString:matchingElement]){if(!soapResults){soapResults=[[NSMutableStringalloc]init];}elementFound=YES;}}// 追加找到的元素值,一个元素值可能要分几次追加-(void)parser:(NSXMLParser*)parser foundCharacters:(NSString*)string{if(elementFound){[soapResults appendString:string];}}// 结束解析这个元素名-(void)parser:(NSXMLParser*)parser didEndElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qName{if([elementName isEqualToString:matchingElement]){UIAlertView*alert=[[UIAlertViewalloc]initWithTitle:@"手机号码信息"message:[NSStringstringWithFormat:@"%@",soapResults]delegate:selfcancelButtonTitle:@"确定"otherButtonTitles:nil];[alert show];elementFound=FALSE;// 强制放弃解析[xmlParser abortParsing];}}// 解析整个文件结束后-(void)parserDidEndDocument:(NSXMLParser*)parser{if(soapResults){soapResults=nil;}}// 出错时,例如强制结束解析-(void)parser:(NSXMLParser*)parser parseErrorOccurred:(NSError*)parseError{if(soapResults){soapResults=nil;}}
6、运行
其中,输入号码时单击查询,打印出的响应XML如下: