Search code examples
objective-cgithub-mantle

How to make a single variable based on NSDictionary parameters?


Data from the server

{
    "type": "reward",
    "stamp_pos": "1",
    "reward_id": "350",
    "reward_title": "dfddffd",
    "reward_cost": "1",
    "reward_cost_text": "Stamp Reward",
    "reward_tnc": "12pm between Monday - Thursday.",
    "member_reward_tracker_id": "1180",
    "redeem_now": "1",
    "redeemed": "0",
    "active": "1",
    "redeemed_date": "0000-00-00 00:00:00",
    "reward_featured_image": "rs/img/someimage"
},

What I am trying to do is

My Model.h

typedef NS_ENUM(NSInteger, CardType) {
    CardTypeStampAvailable = 1,
    CardTypeStampRedeemed,
    CardTypeRewardAvailable,
    CardTypeRewardRedeemNow,
    CardTypeRewardRedeemed,
};
@interface ModelCardReward : MTLModel <MTLJSONSerializing>

@property(nonatomic) CardType myCardType;
@property(nonatomic, strong) NSString *rewardTitle
@property(nonatomic, strong) NSString *rewardCostText;
@end

My Model.m

@implementation ModelCard

+ (NSDictionary *)JSONKeyPathsByPropertyKey {

    return @{
         @"rewardTitle" : @"reward_title",
         @"rewardCostText" : @"reward_cost",
         };
}

I want to have the variable myCardType to have the NS_ENUM value based on the dictionary parameters.

That is

if ([json[@"type"] isEqualToString:reward] && [json[@"redeem_now"] isEqualToString:@"1"]) {

    myCardType = CardTypeRewardAvailable;
}

Any help would be great.


Solution

  • You can achieve this in Mantle 2 with a custom NSValueTransformer and by mapping your property to multiple JSON fields. The example below should be clear.

    ModelCardReward.h

    typedef NS_ENUM(NSInteger, CardType) {
        CardTypeStampAvailable = 1,
        CardTypeStampRedeemed,
        CardTypeRewardAvailable,
        CardTypeRewardRedeemNow,
        CardTypeRewardRedeemed,
    };
    
    @interface ModelCardReward : MTLModel <MTLJSONSerializing>
    @property(nonatomic) CardType myCardType;
    @property(nonatomic, strong) NSString *rewardTitle;
    @property(nonatomic, strong) NSString *rewardCostText;
    @end
    

    ModelCardReward.m

    #import "ModelCardReward.h"
    
    @implementation ModelCardReward
    
    + (NSDictionary *)JSONKeyPathsByPropertyKey {
    
        return @{
            @"myCardType" : @[ @"type", @"redeem_now" ],
            @"rewardTitle" : @"reward_title",
            @"rewardCostText" : @"reward_cost",
        };
    }
    
    + (NSValueTransformer *)myCardTypeJSONTransformer {
        return [MTLValueTransformer transformerUsingForwardBlock:^NSNumber *(NSDictionary *value, BOOL *success, NSError *__autoreleasing *error) {
    
            if ([value[@"type"] isEqualToString:@"reward"] && [value[@"redeem_now"] isEqualToString:@"1"]) {
                return @(CardTypeRewardAvailable);
            }
    
            //logic for other enum values
    
            //return some default value
            return @(CardTypeRewardRedeemed);
    
        }];
    }
    
    @end
    

    Calling code:

    NSDictionary *dict = @{
        @"type": @"reward",
        @"stamp_pos": @"1",
        @"reward_id": @"350",
        @"reward_title": @"dfddffd",
        @"reward_cost": @"1",
        @"reward_cost_text": @"Stamp Reward",
        @"reward_tnc": @"12pm between Monday - Thursday.",
        @"member_reward_tracker_id": @"1180",
        @"redeem_now": @"1",
        @"redeemed": @"0",
        @"active": @"1",
        @"redeemed_date": @"0000-00-00 00:00:00",
        @"reward_featured_image": @"rs/img/someimage"
    };
    
    NSError *error = nil;
    ModelCardReward *model = [MTLJSONAdapter modelOfClass:ModelCardReward.class fromJSONDictionary:dict error:&error];
    if (error) {
        NSLog(@"Error creating model from JSON is %@", error);
    } else {
        NSLog(@"Model is %@", model);
    }