使用的WebService是http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
其中的getWeatherByCityName函数
常使用的技术有:SOAP,HTTP GET, HTTP POST三种方式
(一) SOAP(简单对象访问协议)方式
当你使用SOAP时,必须用到POST方式
(1) SOAP 1.1
以下是请求实例:
POST /WebServices/WeatherWebService.asmx HTTP/1.1 Host: www.webxml.com.cn Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://WebXml.com.cn/getWeatherbyCityName" <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <getWeatherbyCityName xmlns="http://WebXml.com.cn/"> <theCityName>string</theCityName> </getWeatherbyCityName> </soap:Body> </soap:Envelope>
请求方法:
- (void) soap1_1 { NSString *province=[NSString stringWithFormat:@"上海"]; //设置soap请求信息 NSString *soapString=[[NSString alloc] initWithFormat:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>" "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" "<soap:Body>" "<getWeatherbyCityName xmlns=\"http://WebXml.com.cn/\">" "<theCityName>%@</theCityName>" "</getWeatherbyCityName>" "</soap:Body>" "</soap:Envelope>",province]; NSLog(@"%@",soapString); //soap请求地址 NSURL *url=[[NSURL alloc] initWithString:@"http://www.webxml.com.cn/WebServices/WeatherWebService.asmx"]; //请求 NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url]; //设置请求头部 设置ContentType [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 设置SOAPAction [request addValue:@"http://WebXml.com.cn/getWeatherbyCityName" forHTTPHeaderField:@"SOAPAction"]; //设置Content-length [request addValue:[NSString stringWithFormat:@"%d",[soapString length]] forHTTPHeaderField:@"Content-Length"]; //设置请求类型 POST或GET [request setHTTPMethod:@"POST"]; //设置请求Body(只有post方式有) [request setHTTPBody:[soapString dataUsingEncoding:NSUTF8StringEncoding]]; //连接 NSURLConnection *connection=[NSURLConnection connectionWithRequest:request delegate:self]; if (connection) { webData=[NSMutableData data]; } }
(2) SOAP 1.2(除了soap不一样外,其他都一样)
以下是请求实例:
POST /WebServices/WeatherWebService.asmx HTTP/1.1 Host: www.webxml.com.cn Content-Type: application/soap+xml; charset=utf-8 Content-Length: length <?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> <getWeatherbyCityName xmlns="http://WebXml.com.cn/"> <theCityName>string</theCityName> </getWeatherbyCityName> </soap12:Body> </soap12:Envelope>
请求方法:
- (void) soap1_2 { NSString *province=[NSString stringWithFormat:@"上海"]; //设置soap请求信息 NSString *soapString=[[NSString alloc] initWithFormat:@"<?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>" "<getWeatherbyCityName xmlns=\"http://WebXml.com.cn/\">" "<theCityName>%@</theCityName>" "<theCityName>%@</theCityName>" "</getWeatherbyCityName>" "</soap12:Body>" "</soap12:Envelope>",province]; NSLog(@"%@",soapString); //soap请求地址 NSURL *url=[[NSURL alloc] initWithString:@"http://www.webxml.com.cn/WebServices/WeatherWebService.asmx"]; //请求 NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url]; //设置请求头部 设置ContentType [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 设置SOAPAction [request addValue:@"http://WebXml.com.cn/getWeatherbyCityName" forHTTPHeaderField:@"SOAPAction"]; //设置Content-length [request addValue:[NSString stringWithFormat:@"%d",[soapString length]] forHTTPHeaderField:@"Content-Length"]; //设置请求类型 POST或GET [request setHTTPMethod:@"POST"]; //设置请求Body(只有post方式有) [request setHTTPBody:[soapString dataUsingEncoding:NSUTF8StringEncoding]]; //连接 NSURLConnection *connection=[NSURLConnection connectionWithRequest:request delegate:self]; if (connection) { webData=[NSMutableData data]; } }
其实和soap1.1除了soap不一样 ,几乎全一样
(二) HTTP POST方式
请求实例:
POST /WebServices/WeatherWebService.asmx/getWeatherbyCityName HTTP/1.1 Host: www.webxml.com.cn Content-Type: application/x-www-form-urlencoded Content-Length: length theCityName=string
方法:
- (void) httpPost { NSString *postString=@"theCityName=上海"; //此处的URL是POST /WebServices/WeatherWebService.asmx/getWeatherbyCityName 见上! NSURL *url=[NSURL URLWithString:@"http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getWeatherbyCityName"]; NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url]; [request addValue:@"application/x-www-form-urlencoded"forHTTPHeaderField:@"Content-Type"];//注意是中划线 [request addValue:[NSString stringWithFormat:@"%d",[postString length]] forHTTPHeaderField:@"Content-Length"]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]]; NSURLConnection *connection=[NSURLConnection connectionWithRequest:request delegate:self]; if (connection) { webData=[NSMutableData data]; } }
以上三种任选一种都可以。下面开始写余下的程序代码了。
——————ViewController文件——————
#import <UIKit/UIKit.h> @interface WebServiceViewController : UIViewController<NSURLConnectionDelegate,NSURLConnectionDataDelegate> { NSMutableData *webData; NSMutableArray *parserObjects; } @property (strong, nonatomic) NSMutableData *webData; @property (strong, nonatomic) NSString *m_strCurrentElement; @property (strong, nonatomic) NSMutableString *tempString; @end
——————NSURLConnectionDelegate,NSURLConnectionDataDelegate实现方法——————
//接收相应的时候触发 -(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ [webData setLength:0]; } //接收数据的时候触发 -(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ [webData appendData:data]; } //全部完成时触发 -(void) connectionDidFinishLoading:(NSURLConnection *)connection{ NSString *dataString=[[NSString alloc] initWithBytes:[webData bytes] length:[webData length] encoding:NSUTF8StringEncoding]; NSLog(@"%@",dataString); //XML解析 NSXMLParser *xmlParser=[[NSXMLParser alloc] initWithData:webData]; [xmlParser setDelegate:self]; [xmlParser setShouldResolveExternalEntities:YES]; [xmlParser parse]; } //发生异常触发 -(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ NSLog(@"Error:%@",error); }
现在就应该能看到打印出来的返回数据了,我查了一些资料没找到webserive的解析,我只能用xml解析。
正好我可以学习一下xml的解析:
添加协议NSXMLParserDelegate
然后在
-(void) connectionDidFinishLoading:(NSURLConnection *)connection
方法里添加下面代码:
//XML解析 NSXMLParser *xmlParser=[[NSXMLParser alloc] initWithData:webData]; [xmlParser setDelegate:self]; [xmlParser setShouldResolveExternalEntities:YES]; [xmlParser parse];
—————— NSXMLParserDelegate实现方法——————
//开始时触发 - (void)parserDidStartDocument:(NSXMLParser *)parser { parserObjects = [[NSMutableArray alloc] init]; //每一组信息都用数组来存,最后得到的数据即在此数组中 } //解析xml标签对,开始时触发 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict { NSLog(@">>>%@",elementName); if ([elementName isEqualToString:@"ArrayOfString"]) { //开始解析ArrayOfString节点 NSLog(@"开始"); }else { //开始解析子节点 if ([elementName isEqualToString:@"string"]) { self.m_strCurrentElement = @"string"; self.tempString = [NSMutableString string]; } } } //找到标签时 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { NSLog(@"found %@",self.m_strCurrentElement); //填充string if (self.m_strCurrentElement) { [self.tempString appendString:string]; NSLog(@"found is %@",string); } } //解析xml标签对,结束时触发 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { NSLog(@"end %@",self.m_strCurrentElement); //填充 if (self.m_strCurrentElement) { [parserObjects addObject:self.tempString]; self.m_strCurrentElement = nil; self.tempString = nil; } //结束解析ArrayOfString节点 if ([elementName isEqualToString:@"ArrayOfString"]) { NSLog(@"结束"); } } //结束时触发 - (void)parserDidEndDocument:(NSXMLParser *)parser { //由于标签对的名字都是一样的,只能这样获得 //天气图片 NSString *weatherImageName = [parserObjects objectAtIndex:8]; //今日天气实况 NSString *temperature = [parserObjects objectAtIndex:10]; NSString *imageName = [NSString stringWithFormat:@"a_%@",weatherImageName]; [self gifImageView:imageName]; [self.wendu setText:[self segmentation:temperature]]; }
由于今日天气实况的格式是:
今日天气实况:气温:26℃;风向/风力:北风 1级;湿度:78%;空气质量:良;紫外线强度:弱
有时只需要气温,这样我们就要分割这个字符串,分割这个字符串有两种方法:分段,正则表达式。
1.分段
#pragma 分割 - (NSString *)segmentation:(NSString *)segmentationString { //今日天气实况:气温:26℃;风向/风力:北风 1级;湿度:78%;空气质量:良;紫外线强度:弱 //取出 ————> 26℃ NSArray *segmentationArray1 = [segmentationString componentsSeparatedByString:@";"]; NSString *segmentationString1 = [segmentationArray1 objectAtIndex:0]; //今日天气实况:气温:26℃; NSArray *segmentationArray2 = [segmentationString1 componentsSeparatedByString:@":"]; NSString *segmentationResult = [segmentationArray2 objectAtIndex:2]; NSLog(@"segmentation : %@",segmentationResult); return segmentationResult; }
2.正则表达式
#pragma 正则表达式 - (void)regular:(NSString *)regularString { //今日天气实况:气温:26℃;风向/风力:北风 1级;湿度:78%;空气质量:良;紫外线强度:弱 //取出 ————> 26℃ NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[0-9]*℃" options:0 error:nil]; //系统通过自有类NSRegularExpression和NSTextCheckingResult来实现正则表达式的创建和筛选 if (regex != nil) { NSTextCheckingResult *firstMatch = [regex firstMatchInString:regularString options:0 range:NSMakeRange(0, [regularString length])]; if (firstMatch) { NSRange resultRange = [firstMatch rangeAtIndex:0]; //从regularString中截取数据 NSString *result = [regularString substringWithRange:resultRange]; NSLog(@"regular %@",result); } } }
这样就可以只显示气温了。
有时候气温图片需要gif图
显示gif图的方法:
-(void)gifImageView:(NSString *)imageName { NSLog(@"%@",imageName); // 设定位置和大小 CGRect frame = CGRectMake(50,50,0,0); frame.size = [UIImage imageNamed:imageName].size; NSArray *imageArray = [imageName componentsSeparatedByString:@"."]; // 读取gif图片数据 NSData *gif = [NSData dataWithContentsOfFile: [[NSBundle mainBundle] pathForResource:[imageArray objectAtIndex:0] ofType:[imageArray objectAtIndex:1]]]; // view生成 UIWebView *webView = [[UIWebView alloc] initWithFrame:frame]; webView.userInteractionEnabled = NO;//用户不可交互 [webView loadData:gif MIMEType:@"image/gif" textEncodingName:nil baseURL:nil]; [self.view addSubview:webView]; }
这样就完成了,
这个demo主要就是练习。。有不对或者更好的方法,欢迎一起讨论。谢谢了。。。
源码看附件吧。。。