This occurs when you are using ARC (Automatic Reference Counting) generated code.
I found the place to look on these websites: http://stackoverflow.com/questions/8645637/sudzc-with-ios-5-and-arc
and http://code.google.com/p/sudzc/issues/detail?id=40 but it didn't solve my problem completely.
In my case it was an .Net web service (WCF) and I had to use s:Body in stead of Body in the SUDZC generated file: SoapRequest.m
CXMLNode* element = [[SoapgetNode: [doc rootElement] withName: @"s:Body"] childAtIndex:0];
Found it out by NSLogging the CXML document (I used NSLog tp inspect the cxmldocument ):
CXMLNode* test = [doc rootElement];
NSLog(@"%@",test);
Here I got this:
<CXMLElement 0x68c1a50 [0x68c1b10] s:Envelope <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body><GetUserIDResponse xmlns="http://tempuri.org/"><GetUserIDResult>8</GetUserIDResult></GetUserIDResponse></s:Body> </s:Envelope> >
So if in your case the s:Body still doesn't do the trick, look into the XML code and find out which prefix to use! Soon I will be posting a complete solution using WCF web serivces and SUDZC generator for iOS 5. It will be a local service running on the local network, not available through the internet.
Now an extra finding when you are working with custom objects. In my case I'm using Entity Framework with self tracking entities. There entities are passed over the WCF webservice. SUDZC will generate these objects for you and adds them to a NSMutableArray. But when you look at the objects in the array you will notice all properties are empty or nil. Therefore I had to make another change in the generated objects. In the exemple below I changed the generated code withName: @ChangeTracker ... into withName: @"a:ChangeTracker ... I had to change this for all the properties of the entity. So they were filled with the data coming from the xml!
NSMutableString* s = [superserializeElements];
[s appendFormat: @"<a:CashPayment>%@</a:CashPayment>", (self.CashPayment)?@"true":@"false"];
if (self.ChangeTracker != nil) [s appendString: [self.ChangeTrackerserialize: @"a:ChangeTracker"]];
if (self.City != nil) [s appendFormat: @"<a:City>%@</a:City>", [[self.CitystringByReplacingOccurrencesOfString:@"\""withString:@"""]
Be advised that when you start inserting or updating data, you will also need to change some generated code. You will need to add the namespace to the serialization code in the Soap.h and Soap.m file. The I created an extra method which will add the namespace to the envelope:
// Creates the XML request for the SOAP envelope with optional SOAP headers and an extra given namespace.
+ (NSString*) createEnvelope: (NSString*) method forNamespace: (NSString*) ns withParameters: (NSArray*) params withHeaders: (NSDictionary*) headers withExtraNameSpace: (NSString *) extraNameSpace;
Then in the Soap.m file we implement this method like this:
NSString* const SOAP_PREFIX = @"soapenv";
NSString* const NS_PREFIX = @"tem";
NSString* const SER_PREFIX_URL = @"xmlns:ser=\"http://schemas.microsoft.com/2003/10/Serialization/\"";
NSString* const HTTP_PREFIX = @"http://";
NSUInteger const FORWARD_FLASH_CHARACTER_VALUE = 47;
// Creates the XML request for the SOAP envelope with optional SOAP headers.
+ (NSString*) createEnvelope: (NSString*) method forNamespace: (NSString*) ns
forParameters: (NSString*) params withHeaders: (NSDictionary*) headers withExtraNameSpace: (NSString *) extraNameSpace
{
NSMutableString* s = [NSMutableStringstring];
/* example header <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:gal="http://schemas.datacontract.org/2004/07/MyNamespace">*/
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<"];
[s appendString: SOAP_PREFIX];
[s appendString:@":Envelope xmlns:"];
[s appendString: SOAP_PREFIX];
[s appendString: @"=\"http://schemas.xmlsoap.org/soap/envelope/\" "];
[s appendString:@" xmlns:"];
[s appendString: NS_PREFIX];
[s appendFormat:@"=\"%@\" ",ns ];
[s appendFormat:@"%@ ",SER_PREFIX_URL];
if(extraNameSpace)
{
[s appendFormat:@" %@ >",extraNameSpace];
}
if(headers != nil && headers.count > 0) {
[s appendString: @"<"];
[s appendString: SOAP_PREFIX];
[s appendString:@":Header>"];
for(id key in [headers allKeys]) {
if([[headers objectForKey: key] isMemberOfClass: [SoapNil class]])
{
[s appendFormat: @"<%@ xsi:nil=\"true\"/>", key];
} else {
[s appendString:[Soap serializeHeader:headers forKey:key]];
}
}
[s appendString: @"</"];
[s appendString: SOAP_PREFIX];
[s appendString:@":Header>"];
}
[s appendString: @"<"];
[s appendString: SOAP_PREFIX];
[s appendString:@":Body>"];
NSMutableString* fullMethodName = [NSMutableStringstring];
[fullMethodName appendString:NS_PREFIX];
[fullMethodName appendString:@":"];
[fullMethodName appendString:method];
[s appendFormat: @"<%@>%@</%@>", fullMethodName,[params
stringByReplacingOccurrencesOfString:@"&" withString:@"&"],
fullMethodName];
[s appendString: @"</"];
[s appendString: SOAP_PREFIX];
[s appendString:@":Body>"];
[s appendString: @"</"];
[s appendString: SOAP_PREFIX];
[s appendString:@":Envelope>"];
return s;
}
So in this implementation you see there are more namespaces given. This I discovered after inspecting the WSDL xml and looking for the envelope structure. It could be that in your case the namespace prefix are different. Inspect this yourself.
Then when you call the insert function, just add the extra namespace to the create envelope:
NSString* _envelope = [SoapcreateEnvelope: @"InsertSomething"forNamespace: self.namespacewithParameters: _params withHeaders: self.headers withExtraNameSpace:SOAP_FUNCTION_PREFIX];
The constant SOAP_FUNCTION_PREFIX looks like this:
NSString* const SOAP_FUNCTION_PREFIX = @"xmlns:a=\"http://schemas.datacontract.org/2004/07/MyNamespace\"";