Using Self-signed Certificates with WSMethodInvocationRef

I’ve played quite a lot with the Cocoa methods for doing WebServices: lots of people whinge about how little support is given to SOAP from Cocoa, but I actually think it’s not too bad.

To create a SOAP request is quite complicated, but it’s easy to abstract most of this out.

The first step is to create the WSMethodInvocationRef, using WSMethodInvocationCreate. This takes three arguments, one of which is the endpoint URL, which for most cases will be the same across all of your application’s requests. The second is the method name, and the third is the protocol you are using.

You then just need to set the parameters, namespace, headers and so on. This takes care of generating all of the SOAP Envelope stuff, and you can then just use this object to pass to WSMethodInvocationInvoke. This returns a CFDictionaryRef, which is toll-free bridged with an NSDictionary, and gives you status information, as well as results. Notably, this dictionary contains one with the key “/Result”, which contains another dictionary with all of the result data - and this is the cool part - it has already been converted back from XML into whatever structure it represents!

I’ve wrapped this up a little further into some classes - they are still a little under construction, but I’ll release them on bitbucket or something when I’ve cleaned them up a little. I may even make it into a Framework. Which I have been meaning to learn how to do.

Duck-punch misbehaving software

Recently, I found myself having to interact with an API that uses SOAP. I’ve been using the SOAPpy package. Which has made it possible, but not exactly easy. But that’s not what I am going to write about right now.

In order to make the linking of data between my software and that system easier, I needed to get a dump of the other system’s data, in a CSV that I could send to the client.

So, since the SOAPpy module gives you something that looks dict-y, I thought I’d just be able to pass it to csv.DictWriter’s writerow() method.

Not quite.

See, whilst it supports the python dict-like [key] syntax, the SOAPpy.Types.structType doesn’t support the .get() method, that DictWriter uses to extract the data (indeed, it needs to, to be able to trap missing keys).

So, here is a simple duck-punch (does it quack like a duck? No? Punch it harder so, it quacks!) that enables you to pass a structType object to a DictWriter.writerow() method call:

from SOAPpy.Types import structType
structType.get = lambda x,y,z=None : x[y]

In this case, I was able to use this simple case, as I knew the keys it would be asked for would all exist, but you could make a slightly more complex one that checked to see the key exists, and if not, return z. You need all three arguments in the lambda though, since DictWriter passes them in.