Describe General/WSMakeStubsWSGenerateObjCallingASPNETWebservice here.
To set this up, I have an ASP.NET webservice written in C# with the default namespace of tempuri.org and I have Cocoa stubs generated by General/WSMakeStubs. I encountered several problems getting this working as listed below.
Problem 1 - failure to call asp.net webservice I had to make a couple of changes to make this work - both documented in other places. First of all, the soapAction and methodNamespace were missing in the generated stub file. Also, the kWSSOAPBodyEncodingStyle value was wrong:-
Original code:
Modified code:
Also, .NET requires a SOAP action so the General/WSGeneratedObj.m file needs to be modified to work correctly. The name of the locally declared variable ‘soapAction’ conflicts with the parameter passed in with the same name:
Original code:
NSString* soapAction = @”SOAPAction”; NSDictionary* headers = [self copyHeaderDictionary:1 extraVals:&soapAction extraKeys:&soapAction];
Modified code:
NSString* soapActionKey = @”SOAPAction”; NSDictionary* headers = [self copyHeaderDictionary:1 extraVals:&soapAction extraKeys:&soapActionKey];
At this stage, I can call my ASP.NET web service and retrieve a result as expected.
Problem 2 - each web service call results in a memory leak
This took a while to find but it turns out the General/WSGeneratedObj dealloc never gets called because its retain count doesn’t reach 0. The reason for this is that the General/WSMethodInvocationSetCallBack call towards the end of the createInvocationRef method in General/WSGeneratedObj increments the retain count. This method sets the callback for the asynchronous web service call. The documentation for this method states that you should call the method again passing in NULL for the second and third parameters to clear the invocation. I added this extra call at the end of getResultDictionary in General/WSGenenratedObj to decrement the retain count:-
if(fRef) { // new code WSMethodInvocationSetCallBack(fRef, NULL, NULL); // new code } // new code return fResult; // original code
Now the dealloc is called correctly when the invocation object is released in the generated stub.
Problem 3 - application crashes now dealloc is called
Now dealloc is called and the object various objects are released correctly, but I get a crash in General/NSPopAutoreleasePool indicating that an object is being over-released somewhere. I tracked this down to (I think) the extra release of the General/NSURL in createInvocationRef in General/WSGeneratedObj. It is my understanding that this returns an autoreleased object:-
NSURL* url = [NSURL URLWithString: endpoint]; if (url == NULL) { [self handleError: @”NSURL URLWithString failed in createInvocationRef” errorString:NULL errorDomain:kCFStreamErrorDomainMacOSStatus errorNumber:paramErr]; } else { ref = WSMethodInvocationCreate((CFURLRef) url, (CFStringRef)methodName, (CFStringRef) protocol); // [url release]; remove this line ….