2

Given the following JSON blob:

[
  {
    type: "audio",
    title: "Audio example title",
  },
  {
    type: "video",
    title: "Video example title",
  },
  {
    type: "audio",
    title: "Another audio example title",
  },
]

and two JSONModel model classes (AudioModel, VideoModel). Is it possible to have JSONModel automatically create either one of those model classes based on the type property when it maps JSON to models?

Tobi Kremer
  • 618
  • 6
  • 22

2 Answers2

0

it's possible using for..in loop and checking the type property and creating the Model object based on the type like below

NSMutableArray *audioModelArray = [NSMutableArray alloc] init];
NSMutableArray *videoModelArray = [NSMutableArray alloc] init];

    for(NSdictionary *jsonDict in jsonArray) {
        if(jsonDict[@"type"] isEqualToString:@"audio") {
             AudioModel *audio  = [AudioModel alloc]initWithTitle:jsonDict[@"title"]]; 
            [audioModelArray addObject: audio];
        } else {
          VideoModel *audio  = [VideoModel alloc]  initWithTitle:jsonDict[@"title"]];
         [videoModelArray addObject: audio];
        }
    }

then you can iteration over audioModelArray and videoModelArray objects to access the audoModel and videoModel objects and their properties.

Suhit Patil
  • 11,748
  • 3
  • 50
  • 60
0

A fair bit of discussion has happened around this between the JSONModel contributors. The conclusion seems to be that implementing your own class cluster is the best option.

An example of how you can do this - copied from my comment on the GitHub issue:

+ (Class)subclassForType:(NSInteger)pipeType
{
    switch (pipeType)
    {
        case 1: return MyClassOne.class;
        case 2: return MyClassTwo.class;
    }

    return nil;
}

// JSONModel calls this
- (instancetype)initWithDictionary:(NSDictionary *)dict error:(NSError **)error
{
    if ([self isExclusiveSubclass])
        return [super initWithDictionary:dict error:error];

    self = nil;

    NSInteger type = [dict[@"type"] integerValue];
    Class class = [MyClass subclassForType:type];

    return [[class alloc] initWithDictionary:dict error:error];
}

// returns true if class is a subclass of MyClass (false if class is MyClass)
- (BOOL)isExclusiveSubclass
{
    if (![self isKindOfClass:MyClass.class])
        return false;

    if ([self isMemberOfClass:MyClass.class])
        return false;

    return true;
}
James Billingham
  • 760
  • 8
  • 32