eopeter / sudzc

Automatically exported from code.google.com/p/sudzc
0 stars 0 forks source link

returning only the first object from a list of objects returnd from Webservice #19

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1.For iPhone objective C client code generated through Sudzc for a WSDL.
2. If the Web service output is giving a list of objects it does not 
deserialize all the elements. It only deserialize the first object of the array.
3. Inside connectionDidFinishLoading method of SoapRequest.m class 
if(deserializeTo == nil) {
    output = [Soap deserialize:element];
}
this returns the first object of the array only.

What is the expected output? What do you see instead?
To get an array of objects as the output.

What version of the product are you using? On what operating system?
Mac10.6.5 
Sudzc code generating site for objective C for iPhone alpha 

Please provide any additional information below.

Original issue reported on code.google.com by thera...@gmail.com on 7 Dec 2010 at 4:15

GoogleCodeExporter commented 9 years ago
Used a alternate way and it works since all the required array header files are 
already created from Sudzc. commented part of code inside 
connectionDidFinishLoading and let the handler methods do the array 
manipulations.

Thanks a  million for this project for without which my project would not even 
be.

Original comment by thera...@gmail.com on 7 Dec 2010 at 6:25

GoogleCodeExporter commented 9 years ago
Hi 

 Im need help for the same, Please let me know what changes needs do in connectionDidFinishLoading 

Thanks,
Suhail

Original comment by suhai...@gmail.com on 10 Mar 2011 at 11:15

GoogleCodeExporter commented 9 years ago
3. Inside connectionDidFinishLoading method of SoapRequest.m class 

if(deserializeTo == nil) {
    output = [Soap deserialize:element];
}

I had the same issue, the problem here is that output = [Soap 
deserialize:element] makes a dictionary out of the element, and if you don't 
have for every element a different key it just replaces the elemnts resulting 
in one element.

My workaround was to put in the deserializeTo: (in MyWebservice.m) a 
NSMutableArray ...

SoapRequest* _request = [SoapRequest create: _target action: _action service: 
self soapAction: @"" postData: _envelope deserializeTo: [NSMutableArray array]];

And then in SOAPRequest.m
Commented out //element = [element childAtIndex:0];

CXMLNode* element = [[Soap getNode: [doc rootElement] withName: @"Body"] 
childAtIndex:0];
        if(deserializeTo == nil) {
            output = [Soap deserialize:element];
        } else {
            if([deserializeTo respondsToSelector: @selector(initWithNode:)]) {
                //element = [element childAtIndex:0];!!!!!!!
                output = [deserializeTo initWithNode: element];
            } else {
                NSString* value = [[[element childAtIndex:0] childAtIndex:0] stringValue];
                output = [Soap convert: value toType: deserializeTo];
            }
        }

Voila! I got my String Array

I don't know if this is the right solution ...

Original comment by brc...@gmx.net on 13 Jul 2011 at 8:53

GoogleCodeExporter commented 9 years ago
This is the exact code for the workaround

in   connectionDidFinishLoading method comment out the following

 FROM the following line of code

         if(deserializeTo == nil) {

TO end of that if block ie`; to the beginning of

if(self.action == nil) { self.action = @selector(onload:); }

and change the following method calls at the end of that 
connectionDidFinishLoading method to return the value of the element object

the element that is passed is a CXMLNode  and this can be used to initialize 
the complex object type object thtat is needed

ie:

[[COMPLEX_OBJ_TYPE_NAME alloc] initWithNode:CXMLNode_VARIABLE

Original comment by thera...@gmail.com on 19 Aug 2011 at 9:23

GoogleCodeExporter commented 9 years ago
You do not need to comment, you just need to specify your class as 
deserializeTo parameter of the request. It works like a charm.

Original comment by SlowTree@gmail.com on 6 Sep 2011 at 1:58

GoogleCodeExporter commented 9 years ago
Hi,

I've some sort of same error, but not in the same place : 
the "element = [element childAtIndex:0]" return a good instance of CXMLElement 
(the content of xml, which i've got thanks to NSLog(@"element : %@", element);) 
for my app.

But in my xml, i've lots of items which have the same key (i've put an exemple 
in attached file).

And so, when the "output = [deserializeTo initWithNode: element]" is execute, 
the result give me a dictionary of only one item present in my xml.

And i can't find where could the problem come from...

Thanks for any idea you could have...

Original comment by brun.fre...@gmail.com on 7 Oct 2011 at 7:56

Attachments:

GoogleCodeExporter commented 9 years ago
This is my solution to this problem, basically if the same key appears more 
than once, it puts it into an array. I'm sure it's not an optimal solution, but 
it works for my case.

{{{
+(id)deserializeAsDictionary:(CXMLNode*)element {
    if([element childCount] == 1) {
        CXMLNode* child = [[element children] objectAtIndex:0];
        if([child kind] == CXMLTextKind) {
            return [[[element children] objectAtIndex:0] stringValue];
        }
    }

    NSMutableDictionary* d = [NSMutableDictionary dictionary];
    for(CXMLNode* child in [element children]) {
        id v = [Soap deserialize:child];
        if(v == nil) { v = [NSNull null]; }

        id currentItem = [d objectForKey:[child name]];
        if (currentItem)
        {
            if ([currentItem isKindOfClass: [NSMutableArray class]])
            {
                [(NSMutableArray*)currentItem addObject:v];
                v = currentItem;
            }
            else
            {
                NSMutableArray * list = [NSMutableArray arrayWithObject:currentItem];
                v = list;
            }
        }
        [d setObject:v forKey:[child name]];
    }
    return d;
}
}}}

Original comment by d...@angelhill.net on 4 Apr 2012 at 11:24

GoogleCodeExporter commented 9 years ago
I did something similar to comment #3, but rather than 
deserializeTo:[NSMutableArray array] I simply pass in the class of my response 
type. In my case it inherits from SoapArray so it basically looks like 
deserializeTo:[SoapArray class].

Then to make this work inside of SoapRequest.m I modified 
connectionDidFinishLoading:

if([deserializeTo respondsToSelector: @selector(newWithNode:)]) {
    output = [deserializeTo newWithNode: element];
} else if([deserializeTo respondsToSelector: @selector(initWithNode:)]) {
    element = [element childAtIndex:0];
    output = [deserializeTo initWithNode: element];
} else {
    NSString* value = [[[element childAtIndex:0] childAtIndex:0] stringValue];
    output = [Soap convert: value toType: deserializeTo];
}

The first if statement tries to see if there is a class method newWithNode: and 
then uses that to instantiate the object. Works for me.

Original comment by j...@funktional.com on 18 Apr 2012 at 10:56

GoogleCodeExporter commented 9 years ago

I created my web service with sudzc. A method of my webservice returns an array 
of Bean. the switch that calls this method:

- (void) myMethod: (id) value {

/ / Handle errors
if ([value isKindOfClass: [NSError class]]) {
NSLog (@ \ "% @ \", value);
return;
}

/ / Handle faults
if ([value isKindOfClass: [SoapFault class]]) {
NSLog (@ \ "% @ \", value);
return;
}

SDZreturned * result = (SDZreturned *) value;
NSLog (@ \ "myWSmethod return value:% @ \", result);

}

SDZreturned * result = (SDZreturned *) value; This instruction must receive an 
array of Bean. Instead receives 1 Bean: (why do I get a single Bean? I expect 
to receive many Bean [].

I await your response thank you.

Original comment by infomyde...@gmail.com on 21 Nov 2012 at 10:33

GoogleCodeExporter commented 9 years ago
Change connectionDidFinishLoading method of SoapRequest.m class as in comment 
#3 and #7 should work for you good luck =)

Original comment by thera...@gmail.com on 27 Nov 2012 at 1:31

GoogleCodeExporter commented 9 years ago
Hi,

thank you all for the solutions above, I had the same Problems. Also after i 
deserialized to NSMutableArray i had an array of Something but not my Objects.

Now i modified the soap.m
I added the following code to

if([type hasSuffix:@"ObjectName1"]){
                NSLog(@"has Suffix ObjectName1");
                return [ObjectName1 createWithNode:element];
            } else if([type hasSuffix:@"ObjectName2"]){
                NSLog(@"has Suffix ObjectName2");
                return [ObjectName2 createWithNode:element];
            }...

This way i had got Objects into my array. But i am feeling that its not the 
Perfect solution.

Original comment by The.Stef...@gmail.com on 29 Nov 2012 at 10:14

GoogleCodeExporter commented 9 years ago
This thread has been a great source of info. In my case #5 SlowTree@gmail.com 
lead me to the answer.

SoapRequest* _request = [SoapRequest create: _target action: _action service: 
self soapAction: @"http://tempuri.org/blablabla" postData: _envelope 
deserializeTo: nil];

Originally the code generated above had this at the end "deserializeTo: 
@"NSSTring"

Simply change to "deserializeTo: nil". The connectionDidFinishLoading method 
then correctly creates a Dictionary.

No other changes necessary.

Original comment by mar72...@gmail.com on 12 Feb 2013 at 10:14

GoogleCodeExporter commented 9 years ago
Hi,

I have tried some solutions here but it still not working for me.

I have changed the 'deserializeTo' in my APIService.m to NSDictionary:

        SoapRequest* _request = [SoapRequest create: _target action: _action service: self soapAction: @"" postData: _envelope deserializeTo: [NSDictionary dictionary]];

In the Soap.m, in the deserializeAsDictionary method I put the option in 
comment #7

Then when I receive my 'value' on the handler I'm trying to do this:

NSLog(@"Response: , %@", [value allKeys]);

And I'm getting this: 

2013-09-24 13:51:17.784 ClientF[17610:c07] -[__NSDictionaryI lowercaseString]: 
unrecognized selector sent to instance 0x721be20

With the option in comment #3 I'm getting a NSArray with all the values, 
working OK, the problem is that if I don't have the keys I can't know what that 
value means so I need to get a NSDictionary.

Anyone could help me?
Thanks.

Original comment by Sergiodi...@gmail.com on 24 Sep 2013 at 12:00

GoogleCodeExporter commented 9 years ago
#12 worked for me... Thanks

Original comment by epr...@gmail.com on 23 Aug 2014 at 7:13