Web Services from Cocoa/Objective-C (Take 2)

One solution to the web services from Cocoa problem is using gSoap. It's not 100% to my liking, in that solves web services by reducing them to SOAP and I find that mildly annoying - in my opinion web services tools should do their best to abstract away the transport.

However, gSoap does a nice job of creating pure C code that can be used as a web services client so I'll ignore my reluctance to think of SOAP when talking about web services. I am using complete paths (/Users/diciu/Downloads) because I've not installed gSoap - it makes compiling a bit more verbose but I hate writing in my /usr/ folder. YMMV.

Here's how you build a C web services client to the EchoHeaders sample web service that's part of Apache Axis.

Step 1. WSDL to SOAP

/Users/diciu/Downloads/gsoap-2.7/gsoap/wsdl/wsdl2h -c -o test.h EchoHeaders.wsdl



Step 2. SOAP stub and skeleton creation

/Users/diciu/Downloads/gsoap-2.7/gsoap/bin/macosx/soapcpp2 test.h


This step will create a flurry of XML files and a namespace map file (EchoHeadersSoapBinding.nsmap).

Step 3. Creating a client (test.c)

#include <stdlib.h>
#include "soapH.h"
#include "EchoHeadersSoapBinding.nsmap"

int main()
{
struct soap *soap = soap_new();
char * t;

if(soap_call_ns2__echo(soap, NULL, NULL, "test echo", &t) == SOAP_OK)
{
printf("echo result: >%s<\n", t);
}
else
{
soap_print_fault(soap, stderr);
}
}


Step 4. Compiling the client

gcc test.c soapC.c soapClient.c -I/Users/diciu/Downloads/gsoap-2.7/gsoap/ /Users/diciu/Downloads/gsoap-2.7/gsoap/libgsoap.a


Step 5. Running the client

cristi:webservices diciu$ ./a.out
echo result: >test echo<


Of course, this last step assumes that Apache Axis is running on localhost port 8080, otherwise you will get a SOAP fault:


cristi:webservices diciu$ ./a.out
SOAP 1.1 fault: SOAP-ENV:Client [no subcode]
"Connection refused"
Detail: connect failed in tcp_connect()