Sorry to perhaps ask stupid questions, but I'm still having issues with Objective-C syntax.
So, I've got this SOAP response from my sudzc.com generated code. It should contain a SQL SELECT result with veh_id
and version
as columns.
What I get as a response object is a NSMutableArray,
NSMutableArray* soapArray = (NSMutableArray*)value;
so I walk through it:
unsigned count = [soapArray count];
while (count--) {
id myobj = [soapArray objectAtIndex:count];
NSLog(@"myobj: %@", myobj);
}
What I get as a printout is something like:
myobj: {
item = {
key = version;
value = 1;
};
for each row of the SQL result. If this is a printout of the array element, why is there only the version
column and not also the veh_id
column?
How do I access the value for the key on the object myobj
of type id
? Do I have to cast it first?
That's the XML String returned from the Zend Soap-Server:
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.[myurl].com/soap" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:getActiveVehiclesResponse><return SOAP-ENC:arrayType="ns2:Map[23]" xsi:type="SOAP-ENC:Array"><item xsi:type="ns2:Map"><item><key xsi:type="xsd:string">veh_id</key><value xsi:type="xsd:string">1</value></item><item><key xsi:type="xsd:string">version</key><value xsi:type="xsd:string">1</value></item></item><item xsi:type="ns2:Map"><item><key xsi:type="xsd:string">veh_id</key><value xsi:type="xsd:string">3</value></item><item><key xsi:type="xsd:string">version</key><value xsi:type="xsd:string">1</value></item></item><item xsi:type="ns2:Map"><item><key xsi:type="xsd:string">veh_id</key><value xsi:type="xsd:string">4</value></item><item><key xsi:type="xsd:string">version</key><value xsi:type="xsd:string">1</value></item></item></return></ns1:getActiveVehiclesResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
Finally found the solution! The problem lies within the deserializeAsDictionary function. Since my Soap xml string is structured to have each database column as item - key - value - key - value etc, it adds each column under the key "item" and thus the deserializeAsDictionary function overwrites in the line
[d setObject:v forKey:[child name]]
the already added objects. In a first shot, I have added a column iterator and now call the columns "item1, item2,.." (further optimization might be necessary):
// Deserializes the element in a dictionary.
+(id)deserializeAsDictionary:(CXMLNode*)element {
NSLog(@"deserializeAsDictionary = %@, children: %d", element.stringValue, [element childCount]);
if([element childCount] == 1) {
CXMLNode* child = [[element children] objectAtIndex:0];
if([child kind] == CXMLTextKind) {
NSLog(@"child %@ added", [child stringValue]);
return [[[element children] objectAtIndex:0] stringValue];
}
}
NSMutableDictionary* d = [NSMutableDictionary dictionary];
NSInteger i = 1;
NSString *objKey;
for(CXMLNode* child in [element children]) {
id v = [Soap deserialize:child];
if(v == nil) {
v = [NSNull null];
} else {
if([[child name] isEqualToString:@"(null)"]) {
objKey = [NSString stringWithFormat:@"%@",[child stringValue]];
} else if([[child name] isEqualToString:@"key"] || [[child name] isEqualToString:@"value"]) {
objKey = [NSString stringWithFormat:@"%@",[child name]];
} else {
objKey = [NSString stringWithFormat:@"%@%d",[child name],i++];
}
}
[d setObject:v forKey:objKey];
NSLog(@"child %@ added", objKey);
}
return d;
}
The result array now looks like:
},
{
item1 = {
key = "veh_id";
value = 29;
};
item2 = {
key = version;
value = 1;
};
}