How to populate nested JSON parameters using Objective-C output from swagger-codegen

324 views
Skip to first unread message

john.e...@propellerheads.se

unread,
Jun 15, 2015, 12:52:43 PM6/15/15
to swagger-sw...@googlegroups.com
Hi,

I'm using swagger-codegen for Objective C / iOS.

I have attached an example swagger definition which illustrates what I'm trying to do.
Using that with swagger-codegen, I end up with code like the following.

The question is (as written in the code comment) what Objective-C code is valid for filling in item.smallerItem ?
I know I must give it a JSONModel object, but swagger-codegen does not generate a wrapper-object for SmallerItem.


   
SWGDefaultApi* tehAPI = [[SWGDefaultApi alloc] init];
   
[SWGDefaultApi setBasePath:@"https://test-a-nest.internal.unknownhost.unknown/api/v1"];

   
SWGNestedItem* item = [[SWGNestedItem alloc] init];
   
// ??? what to do here, to fill in "text" under "item.smallerItem" ?
//    item.smallerItem
   
   
[tehAPI addHeader:@"Basic <mybase64encoded_basicauth_pair>" forKey:@"Authorization"];
   
[tehAPI testNestedItemWithCompletionBlock:item
        completionHandler
:^(SWGNestedItem *output, NSError *error) {
           
           
NSString* smallerItemText = [output.smallerItem valueForKey:@"text"];
           
NSLog(@"The text is %@", smallerItemText);
       
}];


I have used nesting like that on output data, and parsed it using the results of swagger-codegen.
The wrapper-objects are still not generated, but the parsing succeeds, and it was fairly easy for me to figure out how to extract the data using basic knowledge about JSONModel.

I have not managed to do it on input-data as in the example above.
What am I missing?

Help appreciated, thanks!
John

swagger-testanest.json

john.e...@propellerheads.se

unread,
Jun 17, 2015, 7:50:07 AM6/17/15
to swagger-sw...@googlegroups.com
Answering my own topic..

I have read some more about JSONModel, and it seems the only way to use that for exporting JSON is to first create wrapper classes which inherit from JSONModel.

This means use of swagger-codegen for Objective C is heavily flawed at the moment:

* No Objective C wrapper classes are generated beyond the top level in the swagger definition.
* Code for reading parsed data (from output of web-API-call) must use valueForKey for any values beyond the top level object, which makes longer and less abstract code.
* Code for writing JSON to parameters for a web-API-call must model all missing classes, since that seems to be the only way with JSONModel. This means we must duplicate a large chunk of the swagger definition inside the Objective C code as manually written objects (which should have been generated).

Am I still missing something?
Is swagger-codegen supposed to be able to generate complete wrapper code for objects containing other objects?
If so, how do I make it happen with a swagger definition like the one I attached to the post above?

A colleague of mine recently filed this issue on a similar topic: https://github.com/swagger-api/swagger-codegen/issues/819
What I describe in this thread is with the data types inside the definitions section of the swagger definition.

Thanks and regards!
John

john.e...@propellerheads.se

unread,
Jun 17, 2015, 9:14:07 AM6/17/15
to swagger-sw...@googlegroups.com
Answering my own topic again..

I found a workaround which is somewhat shorter and less rigid, in the swagger-codegen generated code.
If I pass a simple string instead of the object hierarchy, the code path takes it as raw JSON text instead of a JSONModel hierarchy.

Raw JSON is not very easy to work with, but will mean less work for us per change in the swagger specification, compared to manually coding the JSONModel object hierarchies.
Here's an example, continuing with the swagger definition attached to the first post.

    SWGDefaultApi* tehAPI = [[SWGDefaultApi alloc] init];
   
[SWGDefaultApi setBasePath:@"https://test-a-nest.internal.unknownhost.unknown/api/v1"];


   
NSString* item =
       
@"{" "\n"
         
@"    \"NestedItem\": {" "\n"
       
@"        \"SmallerItem\":{" "\n"
       
@"             \"text\": \"Hello, World!\"" "\n"
       
@"        }" "\n"
       
@"    }" "\n"
       
@"}" "\n";


   
[tehAPI addHeader:@"Basic <mybase64encoded_basicauth_pair>" forKey:@"Authorization"];
   
[tehAPI testNestedItemWithCompletionBlock:item
        completionHandler
:^(SWGNestedItem *output, NSError *error) {
           
           
NSString* smallerItemText = [output.smallerItem valueForKey:@"text"];
           
NSLog(@"The text is %@", smallerItemText);
       
}];

Thanks!
John

john.e...@propellerheads.se

unread,
Jun 17, 2015, 11:03:05 AM6/17/15
to swagger-sw...@googlegroups.com
OK,

I finally got the full meaning of what wing328 meant with "inline definitions" in the sentence "For codegen, inline schema is not supported at the moment."
From the issue also linked above in this thread: https://github.com/swagger-api/swagger-codegen/issues/819

Apparently also nested objects under "definitions" are considered inline.
Any nested objects must thus be broken apart using $ref, before they can work with codegen.

When I do that, the above example turns out exactly as expected, with nothing missing from swagger-codegen.
It's a pity that swagger-codegen does not output a warning or something when it runs into inline definitions and silently ignores them.

Hopefully someone will be helped by this thread, apart from enjoying a laugh while I cluelessly fail to use swagger-codegen properly.

John
Reply all
Reply to author
Forward
0 new messages