iOS 使用ASIHttpRequest调用WebService

使用ASIHttpRequest调用WebService   

工作中,使用iPhone作为已有产品的移动终端,目前做能想到最理想的方式就是恳求产品提供WebService了,还是老习惯,坚决不要零散的代码,继续整理为通用的类,便于拉壮丁快速开发

再次利用现有的资源,使用了ASIHttpRequest v1.8.1,因为项目中使用了Windows集成验证,而这个东西正好提供了响应的验证方式。

还是那句话:只是单纯的希望,大家都能有共享学习的精神!

再一个,项目都是.Net相关的,在浏览器中访问.Net WebService的asmx文件时,会返回一系列帮助文件,让我们了解这个WebService有几个调用方法,每个方法的入口参数是什么,返回值是什么,这次使用了SOAP1.1的规范。

再再一个,这个类并不完善,WebService某个方法的参数,必须是简单的数据类型,如数值、字符等等,不支持数据集等对象,等以后需要了再完善吧,呵呵。

再再再一个,调用后的响应解析,是另一个课题,不在这里讲啦,预报下,如果响应中包含了.Net的数据集,也是自己写了通用类可以解析滴,嘎嘎。

再再再再一个,保证是最后一个再了,代码里面看到这个 [Constant sharedConstant].P_SYSTEM_URL ,就去看看前一篇文章吧,单例模式实现常量存储,哈哈。



1、先看看调用说明:
自定义WebService访问类,需要使用下面这个字符串作为SOAP请求,通过POST的方式,提交给WebService
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST /iwscooperationws/todocenter.asmx HTTP/1.1
Host: 192.168.1.11
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://iws.CP.ws/GetWorkflowToDoCount"
 
<? 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 >
     < GetWorkflowToDoCount xmlns = "http://iws.CP.ws/" >
       < UserName >string</ UserName >
     </ GetWorkflowToDoCount >
   </ soap:Body >
</ soap:Envelope >


在上述的XML中,可以看到这个asmx提供了一个GetWorkflowToDoCount的方法,其参数是UserName,其中的 http://iws.CP.ws/是WebService中自己定义的命名空间。经过对几个WebService的实验发现,除了这几个字符串之外,都是不变的东西,那么这个长长的串串,就复制粘贴留下来,等下一步利用之。



2、.h文件中的声明,注释都放到了.m文件中,这是个人习惯:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
+ (ASIHTTPRequest *)getASISOAP11Request:( NSString *) WebURL
                          webServiceFile:( NSString *) wsFile
                            xmlNameSpace:( NSString *) xmlNS
                          webServiceName:( NSString *) wsName
                            wsParameters:( NSMutableArray *) wsParas;
 
+ ( NSString *)getSOAP11WebServiceResponse:( NSString *) WebURL
                            webServiceFile:( NSString *) wsFile
                              xmlNameSpace:( NSString *) xmlNS
                            webServiceName:( NSString *) wsName
                              wsParameters:( NSMutableArray *) wsParas;
 
+ ( NSString *)getSOAP11WebServiceResponseWithNTLM:( NSString *) WebURL
                                    webServiceFile:( NSString *) wsFile
                                      xmlNameSpace:( NSString *) xmlNS
                                    webServiceName:( NSString *) wsName
                                      wsParameters:( NSMutableArray *) wsParas
                                         userName:( NSString *) userName
                                          passWord:( NSString *) passWord;
 
+ ( NSString *)checkResponseError:( NSString *) theResponse;


3、.m文件的实现之一,生成ASIHttpRequest请求:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
//Mark: 生成SOAP1.1版本的ASIHttp请求
  参数 webURL:                远程WebService的地址,不含*.asmx
  参数 webServiceFile:        远程WebService的访问文件名,如service.asmx
  参数 xmlNS:                    远程WebService的命名空间
  参数 webServiceName:        远程WebService的名称
  参数 wsParameters:            调用参数数组,形式为[参数1名称,参数1值,参数2名称,参数2值⋯⋯],如果没有调用参数,此参数为nil
  */
+ (ASIHTTPRequest *)getASISOAP11Request:( NSString *) WebURL
                          webServiceFile:( NSString *) wsFile
                            xmlNameSpace:( NSString *) xmlNS
                          webServiceName:( NSString *) wsName
                            wsParameters:( NSMutableArray *) wsParas
{
     //1、初始化SOAP消息体
     NSString * soapMsgBody1 = [[ NSString alloc] initWithFormat:
                                @ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
                                "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n"
                                "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" \n"
                                "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
                                "<soap:Body>\n"
                                "<%@ xmlns=\"%@\">\n" , wsName, xmlNS];
     NSString * soapMsgBody2 = [[ NSString alloc] initWithFormat:
                                @ "</%@>\n"
                                "</soap:Body>\n"
                                "</soap:Envelope>" , wsName];
     
     //2、生成SOAP调用参数
     NSString * soapParas = [[ NSString alloc] init];
     soapParas = @ "" ;
     if (![wsParas isEqual: nil ]) {
         int i = 0;
         for (i = 0; i < [wsParas count]; i = i + 2) {
             soapParas = [soapParas stringByAppendingFormat:@ "<%@>%@</%@>\n" ,
                          [wsParas objectAtIndex:i],
                          [wsParas objectAtIndex:i+1],
                          [wsParas objectAtIndex:i]];
         }
     }
     
     //3、生成SOAP消息
     NSString * soapMsg = [soapMsgBody1 stringByAppendingFormat:@ "%@%@" , soapParas, soapMsgBody2];
     
     //请求发送到的路径
     NSURL * url = [ NSURL URLWithString:[ NSString stringWithFormat:@ "%@%@" , WebURL, wsFile]];
     
     //NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
     ASIHTTPRequest * theRequest = [ASIHTTPRequest requestWithURL:url];
     NSString *msgLength = [ NSString stringWithFormat:@ "%d" , [soapMsg length]];
     
     //以下对请求信息添加属性前四句是必有的,第五句是soap信息。
     [theRequest addRequestHeader:@ "Content-Type" value:@ "text/xml; charset=utf-8" ];
     [theRequest addRequestHeader:@ "SOAPAction" value:[ NSString stringWithFormat:@ "%@%@" , xmlNS, wsName]];
     
     [theRequest addRequestHeader:@ "Content-Length" value:msgLength];
     [theRequest setRequestMethod:@ "POST" ];
     [theRequest appendPostData:[soapMsg dataUsingEncoding: NSUTF8StringEncoding ]];
     
     [theRequest setDefaultResponseEncoding: NSUTF8StringEncoding ];
     
     return theRequest;
}


4、.m文件的实现之二,同步调用WebService请求,返回响应字符串
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#pragma mark -
/*
  //Mark: 使用SOAP1.1同步调用WebService请求
  参数 webURL:                远程WebService的地址,不含*.asmx
  参数 webServiceFile:        远程WebService的访问文件名,如service.asmx
  参数 xmlNS:                    远程WebService的命名空间
  参数 webServiceName:        远程WebService的名称
  参数 wsParameters:            调用参数数组,形式为[参数1名称,参数1值,参数2名称,参数2值⋯⋯],如果没有调用参数,此参数为nil
  */
+ ( NSString *)getSOAP11WebServiceResponse:( NSString *) WebURL
                            webServiceFile:( NSString *) wsFile
                              xmlNameSpace:( NSString *) xmlNS
                            webServiceName:( NSString *) wsName
                              wsParameters:( NSMutableArray *) wsParas
{
     //创建请求
     ASIHTTPRequest * theRequest = [ self getASISOAP11Request:WebURL
                                              webServiceFile:wsFile
                                                xmlNameSpace:xmlNS
                                              webServiceName:wsName
                                                wsParameters:wsParas];
     
     //显示网络请求信息在status bar上
     [ASIHTTPRequest setShouldUpdateNetworkActivityIndicator: YES ];
     
     //同步调用
     [theRequest startSynchronous];
     NSError *error = [theRequest error];
     if (!error) {
         return [theRequest responseString];
     }
     else {
         //出现调用错误,则使用错误前缀+错误描述
         return [ NSString stringWithFormat:@ "%@%@" , [Constant sharedConstant].G_WEBSERVICE_ERROR, [error localizedDescription]];
     }
}


5、.m文件实现之三,同步调用需要Windows集成验证的WebService请求,返回响应字符串:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#pragma mark -
/*
  //Mark: 使用SOAP1.1同步调用WebService请求,需提供Windows集成验证的用户名、密码和域
  参数 webURL:                远程WebService的地址,不含*.asmx
  参数 webServiceFile:        远程WebService的访问文件名,如service.asmx
  参数 xmlNS:                    远程WebService的命名空间
  参数 webServiceName:        远程WebService的名称
  参数 wsParameters:            调用参数数组,形式为[参数1名称,参数1值,参数2名称,参数2值⋯⋯],如果没有调用参数,此参数为nil
  参数 userName                用户名--目前来看,不需要输入域信息
  参数 passWord                密码
  */
+ ( NSString *)getSOAP11WebServiceResponseWithNTLM:( NSString *) WebURL
                                    webServiceFile:( NSString *) wsFile
                                      xmlNameSpace:( NSString *) xmlNS
                                    webServiceName:( NSString *) wsName
                                      wsParameters:( NSMutableArray *) wsParas
                                          userName:( NSString *) userName
                                          passWord:( NSString *) passWord
{
     //创建请求
     ASIHTTPRequest * theRequest = [ self getASISOAP11Request:WebURL
                                              webServiceFile:wsFile
                                                xmlNameSpace:xmlNS
                                              webServiceName:wsName
                                                wsParameters:wsParas];
     
     //集成验证NTLM用户名,密码和域设置
     [theRequest setUsername:userName];
     [theRequest setPassword:passWord];
     //[theRequest setDomain:doMain];
     
     //显示网络请求信息在status bar上
     [ASIHTTPRequest setShouldUpdateNetworkActivityIndicator: YES ];
     
     //同步调用
     [theRequest startSynchronous];
     NSError *error = [theRequest error];
     if (!error) {
         return [theRequest responseString];
     }
     else {
         //出现调用错误,则使用错误前缀+错误描述
         return [ NSString stringWithFormat:@ "%@%@" , [Constant sharedConstant].G_WEBSERVICE_ERROR, [error localizedDescription]];
     }
}


6、.m文件实现之四,响应字符串中是否包含错误信息,简单处理了下错误消息的中文显示:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#pragma mark -
/*
  //Mark: 检查WebService的Response是否包含错误信息
     如果未包含错误,则返回零长度字符串
     否则返回错误描述
     错误信息格式:错误前缀\n错误描述
  */
+ ( NSString *)checkResponseError:( NSString *) theResponse
{
     //检查消息是否包含错误前缀
     if (![theResponse hasPrefix:[Constant sharedConstant].G_WEBSERVICE_ERROR]) {
         return @ "" ;
     }
     else {
         NSMutableString *sTemp = [[ NSMutableString alloc] initWithString:theResponse];
         //获取错误前缀的范围
         NSRange range=[sTemp rangeOfString:[Constant sharedConstant].G_WEBSERVICE_ERROR];
         //剔除错误前缀
         [sTemp replaceCharactersInRange:range withString:@ "" ];
         
         NSString * errMsg = sTemp;
         //Authentication needed
         if ([sTemp isEqualToString:@ "Authentication needed" ]) {
             errMsg = @ "用户登录失败!" ;
         }
         //The request timed out
         if ([sTemp isEqualToString:@ "The request timed out" ]) {
             errMsg = @ "访问超时,请检查远程地址等基本设置!" ;
         }
         //The request was cancelled
         if ([sTemp isEqualToString:@ "The request was cancelled" ]) {
             errMsg = @ "请求被撤销!" ;
         }
         //Unable to create request (bad url?)
         if ([sTemp isEqualToString:@ "Unable to create request (bad url?)" ]) {
             errMsg = @ "无法创建请求,错误的URL地址!" ;
         }
         //The request failed because it redirected too many times
         if ([sTemp isEqualToString:@ "The request failed because it redirected too many times" ]) {
             errMsg = @ "请求失败,可能是因为被重定向次数过多!" ;
         }
         //A connection failure occurred
         if ([sTemp isEqualToString:@ "A connection failure occurred" ]) {
             errMsg = @ "网络连接错误,请检查无线或3G网络设置!" ;
         }
         
         return errMsg;
     }
}


7、开始调用啦:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
     //创建WebService的调用参数
     NSMutableArray * wsParas = [[ NSMutableArray alloc] initWithObjects:
                                 @ "UserName" , [Constant sharedConstant].P_USER_NAME,
                                 nil ];
     
     //调用WebService,获取响应
     NSString * theResponse = [WebService getSOAP11WebServiceResponseWithNTLM:[Constant sharedConstant].P_SYSTEM_URL        
                                                               webServiceFile:[Constant sharedConstant].G_WS_TODOCENTER
                                                                 xmlNameSpace:[Constant sharedConstant].G_WEBSERVICE_NAMESPACE
                                                               webServiceName:[Constant sharedConstant].G_WS_TODOCENTER_GETWORKFLOWTODOCOUNT
                                                                 wsParameters:wsParas
                                                                     userName:[Constant sharedConstant].P_USER_NAME
                                                                     passWord:[Constant sharedConstant].P_PASSWORD];
     
     //检查响应中是否包含错误
     NSString * errMsg = [WebService checkResponseError:theResponse];
     
     //接下来的代码就是检查errMsg有没有内容
     //再接下来就是theResponse响应字符串的解析了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值