wsdl2objc: Pain points integrating with a WCF service.

First, figure out if the service you wrote is accepting SOAP 1.2 messages. SOAP 1.2 messages have name spaces that look like “http://www.w3.org/” while SOAP 1.1 messages look like “schemas.xmlsoap.org”.

Spare yourself the trouble, make a quick test project and try sending a request. Here the code I was using:

@interface TYViewController ()
@end
@implementation TYViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a nib.
    CustomBinding_HealthSync *binding = [HealthSyncBroker CustomBinding_HealthSync];
    [binding setLogXMLInOut:YES];
    tns1_AuthenticateDevice *authenticateDevice = [[tns1_AuthenticateDevice alloc] init];
    authenticateDevice.DeviceID = @"TESTTESTTEST";
    [binding AuthenticateDeviceAsyncUsingParameters:authenticateDevice delegate:self];
}
- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    } else {
        return YES;
    }
}
#pragma mark BasicHTTPBinding_HealthSync
-(void)operation:(CustomBinding_HealthSyncOperation *)operation completedWithResponse:(CustomBinding_HealthSyncResponse *)response {
    NSArray *responseBody = [response bodyParts];
    NSLog(@"%@", responseBody);
    if(response.error) {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"" message:@"" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [alertView show];
    }
    for (id bodyPart in responseBody) {
        tns1_AuthenticateDeviceResponse *body = (tns1_AuthenticateDeviceResponse *) bodyPart; 
        if([[body AuthenticateDeviceResult] boolValue]) {

        }
        else {
 }
 }
}

Now, look at this method:

- (void)sendHTTPCallUsingBody:(NSString *)outputBody soapAction:(NSString *)soapAction forOperation:(SomeBinding_SomeOperation *)operation

This is pretty much the only place you’d be making changes. If you’re using SOAP 1.1, change the request content-type header from “application/soap+xml” to “text/xml”. (Do a project wide search for “application/soap+xml”).

If you’re using Soap 1.2, there’s a bug in wsdl2objc which causes it to generate a SOAPAction header instead of an action header. This should give you an error that looks something like this:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body><s:Fault><s:Code><s:Value>s:Sender</s:Value><s:Subcode><s:Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</s:Value></s:Subcode></s:Code><s:Reason><s:Text xml:lang="en-US">The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver.  Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).</s:Text></s:Reason></s:Fault></s:Body></s:Envelope>

If it does, replace the following lines:

[request setValue:soapAction forHTTPHeaderField:@"SOAPAction"];
[request setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];

with:

NSString *contentType = [NSString stringWithFormat:@"application/soap+xml; charset=utf-8; action=\"%@\"", soapAction];
[request setValue:contentType forHTTPHeaderField:@"Content-Type"];

If you do all this and it still isn’t fixed, try using SoapUI to look at the raw request. Look at the headers and body that it produces. Put your <s:envelope> generated by wsdl2objc in SoapUI’s body (clearing out the soap request that it autogenerated) and play around with it. That usually fixes things.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s