<iOS>网络编程(一)SOAP, WSDL, Web Service

来源:互联网 发布:mac word 导航栏 编辑:程序博客网 时间:2024/06/10 03:08

这段时间, 为了统一一下自己关于网络编程的思想, 特写下该系列教程,如有误,请指正。多谢。

前提, 为了熟悉接下来的教程,需要读者有如下相关知识, SOAP, WSDL, Web Service. 

了解这三个东东最好的地方是:

SOAP: http://www.w3school.com.cn/soap/index.asp

WSDL:http://www.w3school.com.cn/wsdl/index.asp

Web Service: http://www.w3school.com.cn/webservices/index.asp

http://www.w3school.com.cn 真的很不错, 讲得浅显易懂。

目标-: 通过SOAP方式获取网络数据, 用请求<-->响应 的方式来实现。 先转载一种简单的方式来做, 然后再分析这种方式的不足。

详细步骤是英文的, 这里就不翻译了哈?

I needed to access a SOAP-based web service from the iPhone. There are a wide variety of opinions on how to go about this: "One word: Don't" was one poster's reply to a related question at Stackoverflow.com. Some people suggest writing one's own routines, while others suggest trying various code-generating tools. One I found was called gSoap, but apparently there is a fair amount of work yet to do to get it working with the iPhone. I found wsdl2objc which generates Objective-C code from a WSDL so you can call SOAP services. I want to show you how I used WSDL2ObjC to access a SOAP based web service.

Here's what you need to get started:

    * WSDL2ObjC. I'm going to use WSDL2ObjC-0.7-pre1.zip for this tutorial.可以从这个地址下载, :http://code.google.com/p/wsdl2ob ... ip&can=2&q=, 下载下来后, 运行时, 上面一行输入你要进行解析的wsdl网址,或者输入本地wsdl文件的地址, 下面一行输入要生成的代码的位置, 后面将使用这些生成的代码来完成soap请求和数据回复。---smking.
    * A web service to consume. For this tutorial, we'll use the "LocalTime" service (http://www.ripedevelopment.com/webservices/LocalTime.asmx) which will, given a zip code, provide the local time for that zip code.


Let's go.

1. Generate the stubs with WSDL2ObjC.
Start WSDL2ObjC. In the first field, enter the name of the source WSDL. You can specify a local file, or a web address. For here, enter http://www.ripedevelopment.com/webservices/LocalTime.asmx?wsdlIn the second field, specify a directory in which WSDL2ObjC will create the new files. You can use the Browse button to specify a directory. When you click "Parse WSDL", you will see a few messages, one of which should say it is generating Objective C Code into the output directory. Check the target directory to make sure your files are there.

然后创建一个xcode项目, 这里为了简单方便, 使用一个按钮,一个textview来显示返回的数据即可。具体过程不表, 如有不懂的, 可以先去查查关于xcode的帮助信息。

Now wire the button's Touch Up Inside event to the buttonPressed action, and connect the field's outlet to field. Save and close Interface Builder.

Go ahead and build and run, just to make sure everything's OK so far. I expect it is, but it doesn't hurt to check.

3. Pull in the WSDL2ObjC generated code.
Let's pull in the code WSDL2ObjC wrote for us: in "Other Sources," add a new Group named "LocalTime". With Finder, drag all the files that it created into the new group. Tell Xcode to copy the items into the destination folder.

Take a look at LocalTime.h. There's a ton of stuff there: definitions for bindings, responses, requests, etc. This code corresponds to the data that WSDL2ObjC pulled out of LocalTime's WSDL.

Before compiling from this point, make sure you have followed the instructions in the wiki page UsageInstructions (ie, the linker flags properties and frameworks). You find UsageInstructions at the WSDL2ObjC project home page. Incidentally, the first character of the Other C Flags property is the capital letter I as in India. You're welcome.

总结一下第三步 , 就是把要之前生成的代码部分拖入到项目中, 并加入framework: CFNetwork.framework, libxml2.dylib. 

然后还需要在Targests/ Build Settings下的Header Search Paths下输入"/usr/include/libxml2"(注意不带引号的)。

4. Write.
Let's write some code. Open the .m for your controller. First thing you need to do is #import "LocalTime.h" Now let's fill in the buttonPressed function. Here it is:


- (IBAction)buttonPressed:(id)sender {
  LocalTimeSoapBinding *binding = [[LocalTime LocalTimeSoapBinding] initWithAddress:@"http://www.ripedevelopment.com/webservices/LocalTime.asmx"];
  binding.logXMLInOut = YES;  // to get logging to the console.

  LocalTime_LocalTimeByZipCode *request = [[LocalTime_LocalTimeByZipCode alloc] init];
  request.ZipCode = @"29687";  // insert your zip code here.

  LocalTimeSoapBindingResponse *resp = [binding LocalTimeByZipCodeUsingParameters:request];
  for (id mine in resp.bodyParts)
  {
          if ([mine isKindOfClass:[LocalTime_LocalTimeByZipCodeResponse class]])
          {
                  field.text = [mine LocalTimeByZipCodeResult];
          }
  }
}

The first thing we do is create a binding, and associate it with ripedevelopment's web service endpoint. We then create a request object, fill in the blanks, and then call the service. The service returns a LocalTimeSoapBindingResponse, which we save in resp.

LocalTimeSoapBindingResponse has a field called bodyParts. The code runs through bodyParts, looking for the response to the call. It then stores the result in the field for us to see.

5. Run. 运行之。
Save everything. Under the Run menu, bring up the Console, then build and run. Click the "Test" button on the Simulator. You should see the outbound request, a response of 200, then... Uh oh, "Unexpected response MIME type to SOAP call:text/xml"

What we're going to do here is switch the MIME type from application/soap+xml to text/xml. You can use Xcode's search and replace; you should find four occurrences of application/soap+xml Change them all to text/xml.

Now when you rerun the app, and click the "Test" button, you should see the messages in the console, and then you should see the date appear in the field.

So there you have it. Now I know I didn't show how to make an asynchronous call, nor did I talk about complex types. That's what next time is for.


总结一下这种方式:很明显, 看起来使用的代码还是比较简单的, 尽管, 引入的代码比较复杂。 

但是, 我个人觉得, 如果你只需要调用那么几次,向同一个服务器, 也就是只有那么几种请求, 业务比较简单的情况下, 可以使用上面的这种方式, 还可以忍受, 因为如你所见, 上面引入了好几个新的类LocalTimeSoapBindingResponse, LocalTimeSoapBinding, 什么的, 在使用的过程中, 编码将不是那么容易, 因为你可能是依赖于这几个类, 你还得去把这几个类给搞明白。 

但它的方便之处在于, 简单, 易于使用。 

为了不使咱们的代码依赖于这个工具生成的代码, 我们接下来要讲的是如何直接用原始代码,或者是ios 的sdk来去做同样的事情。

(PS:上面的代码应该采用建线程的方式来请求,但这里为了简化 ,没有那样做。)


原创粉丝点击