您的位置:首页 > 理论基础 > 计算机网络

iOS学习之2-使用ASIHttpRequest调用WebService

2012-08-17 18:12 543 查看
2012年04月10日 星期二 9:50
工作中,使用iPhone作为已有产品的移动终端,目前做能想到最理想的方式就是恳求产品提供WebService了,还是老习惯,坚决不要零散的代码,继续整理为通用的类,便于拉壮丁快速开发,虽然目前的壮丁就俺一个,hoho

再次利用现有的资源,使用了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"

<?xmlversion="1.0"encoding="utf-8"?>

<soap:Envelopexmlns: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>

<GetWorkflowToDoCountxmlns="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 = [[NSStringalloc] 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 = [[NSStringalloc] initWithFormat:

@"</%@>\n"

"</soap:Body>\n"

"</soap:Envelope>", wsName];

//2、生成SOAP调用参数

NSString* soapParas = [[NSStringalloc] init];

soapParas = @"";

if(![wsParas isEqual:nil]) {

inti = 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 = [NSURLURLWithString:[NSStringstringWithFormat:@"%@%@", WebURL, wsFile]];

//NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];

ASIHTTPRequest * theRequest = [ASIHTTPRequest requestWithURL:url];

NSString*msgLength = [NSStringstringWithFormat:@"%d", [soapMsg length]];

//以下对请求信息添加属性前四句是必有的,第五句是soap信息。

[theRequest addRequestHeader:@"Content-Type"value:@"text/xml; charset=utf-8"];

[theRequest addRequestHeader:@"SOAPAction"value:[NSStringstringWithFormat:@"%@%@", xmlNS, wsName]];

[theRequest addRequestHeader:@"Content-Length"value:msgLength];

[theRequest setRequestMethod:@"POST"];

[theRequest appendPostData:[soapMsg dataUsingEncoding:NSUTF8StringEncoding]];

[theRequest setDefaultResponseEncoding:NSUTF8StringEncoding];

returntheRequest;

}

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 = [selfgetASISOAP11Request: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[NSStringstringWithFormat:@"%@%@", [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 = [selfgetASISOAP11Request: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[NSStringstringWithFormat:@"%@%@", [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 = [[NSMutableStringalloc] initWithString:theResponse];

//获取错误前缀的范围

NSRangerange=[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网络设置!";

}

returnerrMsg;

}

}

7、开始调用啦:

?
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19
//创建WebService的调用参数

NSMutableArray* wsParas = [[NSMutableArrayalloc] 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响应字符串的解析了

注意这个调用例子里面的WebService的参数UserName和调用windows集成验证时提供的userName,是两回事啊⋯⋯
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: