Debugging SOAP requests in Cocoa


Okay, so let’s say you’re using the (time-honored, if borderline senile) usual way of invoking web services from Cocoa by using WSMakeStubs to generate a skeleton Objective-C stub from your WSDL file like so:

WSMakeStubs -x ObjC -name MyStub -file ihazsoap.wsdl

When things start to go south (and believe me, they will), consider going into WSGeneratedObj.m and changing:

if (ref == NULL)
    [self handleError: @"WSMethodInvocationCreate failed in createInvocationRef" errorString:NULL errorDomain:kCFStreamErrorDomainMacOSStatus errorNumber: paramErr];
else {
    WSMethodInvocationSetProperty(ref, kWSSOAPBodyEncodingStyle, style);

    NSString* soapAction = @"SOAPAction";
    NSDictionary* headers = [self copyHeaderDictionary:1 extraVals:&soapAction extraKeys:&soapAction];
    WSMethodInvocationSetProperty(ref, kWSHTTPExtraHeaders, headers);
    [headers release];

…to read:

if (ref == NULL)
    [self handleError: @"WSMethodInvocationCreate failed in createInvocationRef" errorString:NULL errorDomain:kCFStreamErrorDomainMacOSStatus errorNumber: paramErr];
else {
    WSMethodInvocationSetProperty(ref, kWSSOAPBodyEncodingStyle, style);

    NSString* soapActionKey = @"SOAPAction";
    NSDictionary* headers = [self copyHeaderDictionary:1 extraVals:&soapAction extraKeys:&soapActionKey]; // fix dumb stub bug
    WSMethodInvocationSetProperty(ref, kWSHTTPExtraHeaders, headers);
        // Output debug info
    WSMethodInvocationSetProperty(ref, kWSDebugOutgoingBody,    kCFBooleanTrue);
    WSMethodInvocationSetProperty(ref, kWSDebugOutgoingHeaders, kCFBooleanTrue);
    WSMethodInvocationSetProperty(ref, kWSDebugIncomingBody,    kCFBooleanTrue);
    WSMethodInvocationSetProperty(ref, kWSDebugIncomingHeaders, kCFBooleanTrue);
    [headers release];

Your code won’t magically work, but at least now you can check the Console for what exactly is being sent (especially important if you have finicky HTTPS web services that don’t like the default kWSSOAPStyleRPC invocation style or which like their namespaces to be explicitly declared somewhere odd).

Oh, and my code isn’t working yet. I just wanted to remember this later.