Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MOTIS Object Mapping, With NSDictionary with values NSArray how can I specify type of array elements?

I have the json

{"Types":{ "food":[{"cve":"1","description":"Pizza"},{"cve":"2","description":"Restaurant"},{"cve":"3","description":"Cafe"}], "Health":[{"cve":"3","description":"Pharmacy"},{"cve":"4","description":"Hospital"}] } }

Types.h

#import <Foundation/Foundation.h>

@interface Types: NSObject
@property (nonatomic, copy) NSDictionary *types;

@end

Types.m

#import "Types.h"
#import <Motis/Motis.h>
#import "SubTipo.h"

@implementation Types
+ (NSDictionary*)mts_mapping
{
    return @{@"types": mts_key(types),};
}



@end

Subtype.h

#import <Foundation/Foundation.h>

@interface Subtype: NSObject
@property (nonatomic, assign) int cve;
@property (nonatomic, copy) NSString *description;
@end

Subtype.m

#import "Subtype.h"
#import <Motis/Motis.h>

@implementation Subtype
+ (NSDictionary*)mts_mapping
{
    return @{@"cve": mts_key(cve),
             @"description": mts_key(description),
             };
}

@end

I deserialize with

Types * values=[[Types alloc]init];
 NSDictionary * jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];


    [values mts_setValuesForKeysWithDictionary:jsonObject ];

I get NSDictionary with NSArray of NSDictionary

but I need NSDictionary with NSArray of Subtypes

I try with

+ (NSDictionary*)mts_arrayClassMapping
{
    return @{mts_key(types): Subtype.class};
}

but wasn't successful

How can I get these with Motis

like image 612
Alfredo Zuloaga Avatar asked Mar 19 '23 12:03

Alfredo Zuloaga


1 Answers

As far as I see, your Types object is not properly defined. If you have an attribute of type NSDictionary* and the JSON received is a Dictionary, Motis won't perform any automatic conversion as the types already match (you are receiving a dictionary and your attribute is of type NSDictionary).

Therefore, you must implement your Type object following your JSON structure. This means that your Type object must have two properties of type array, one for food and one for health. Then, using the method +mts_arrayClassMapping you can specify the content type of the arrays to Subtype.

Here the implementation:

// ***** Type.h file ***** //

@interface Type: NSObject

@property (nonatomic, strong) NSArray *food;
@property (nonatomic, strong) NSArray *health;

@end

// ***** Type.m file ***** //

@implementation Type

+ (NSDictionary*)mts_mapping
{
    return @{@"food": mts_key(food),
             @"Health": mts_key(health),
            };
}

+ (NSDictionary*)mts_arrayClassMapping
{
    return @{mts_key(food): Subtype.class,
             mts_key(health): Subtype.class,
            };
}

@end

Regarding the implementation of Subtype, yours is already correct. However, you should not use the property name description as it is already being used by NSObject:

// ***** Subtype.h file ***** //

@interface Subtype: NSObject

@property (nonatomic, assign) NSInteger cve;
@property (nonatomic, copy) NSString *theDescription;

@end

// ***** Subtypes.m file ***** //

@implementation Subtype

+ (NSDictionary*)mts_mapping
{
    return @{@"cve": mts_key(cve),
             @"description": mts_key(theDescription),
             };
}

@end

Finally, as you list above, you can map your JSON, but first you will have to extract the "dictionary" for key Types, which you will map to your "Type" model object.

// Get the json data
NSDictionary * jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

// Extract the JSON dictionary of types.
NSDictionary *jsonType = [jsonObject objectForKey:@"Types"];

// Create a Type object 
Type *type = [[Type alloc] init];

// Map JSON contents to the type object with Motis
[type mts_setValuesForKeysWithDictionary:jsonType];

Hoping this fixes your issue.

like image 132
vilanovi Avatar answered Apr 26 '23 06:04

vilanovi