Wednesday, November 21, 2012

Button in ListView

Many thanks to Adam Toennis who directed me to this stack overflow post that helped resolve an ugly problem.  I'm posting it here so that when I run into this again in 6 months, I can find it easily.

Problem was that we put a button in a list view row.  We obviously want the user to be able to tap the button, but we still wanted the user to tap the row itself too.  Just putting the button in clobbered the row tap.

Answer came from this post: http://stackoverflow.com/questions/3045872/listview-and-buttons-inside-listview

In short,  put android:focusable="false" in the button element.



Monday, March 5, 2012

Ruby, SOAP, and XML Attributes

If you're looking to interface with a SOAP web service from a mobile device -- especially Android -- don't.  The best SOAP library I could find for Android was ksoap2, and it is way to fringe for comfort.

We decided that it would be best to write a RESTful service facade to front the SOAP service instead.  Trying to flesh it out quickly, I turned to Ruby with soap4r, whereupon I ran smack into a problem that took me a few days to track down the resolution to.

The soap request needed to look something like this:

    

Simple, right? Well the hard part is the attribute.  WSDLDriverFactory is not well documented.  Actually, I don't think it is documented at all, but I found examples on the web of how to use it.  You pass your soap method a map of the values, like this:
{:rootElement => {:childElement => {:myId => "123456"}}}
That works great if "myId" is an element contained by childElement, but in our case it's an attribute.  How do you tell the proxy that myId is the value of an attribute, not the valude of an element? You would think that it would be smart enough to figure it out, but it's not. After digging around for hours, I finally found an obscure reference to the answer: you have to prefix the attribute name with "xmlattr_". So the correct map looks like this:
{:rootElement => {:childElement => {:xmlattr_myId => "123456"}}}
The full code looks like:
require 'soap/wsdlDriver'

wsdl = 'http://host:port/some-service?WSDL'

client = SOAP::WSDLDriverFactory.new( wsdl ).create_rpc_driver
client.wiredump_dev = $stdout
client.options["protocol.http.basic_auth"] << [wsdl, 'MY_USER', 'MY_PASSWORD']
result = client.doSomething(
{:rootElement =>
  {:childElement => {:xmlattr_myId => "123456"}}})