Skip to content
This repository has been archived by the owner on Sep 5, 2023. It is now read-only.

Some odd condition after issue #12 #13

Closed
shinrenpan opened this issue May 24, 2014 · 3 comments
Closed

Some odd condition after issue #12 #13

shinrenpan opened this issue May 24, 2014 · 3 comments

Comments

@shinrenpan
Copy link

Example:

source JSON

NSDictionary *JSON = @{@"name" : @"shinrenpan" , @"user_age" : @(35)};

User.h

@interface User : NSObject
@property (copy, nonatomic, readonly) NSString *name;
@end

Condition 1

Did't implement both mts_shouldSetUndefinedKeys and implement +mts_mapping

// User.m
@implementation User
@end
User *user = [[User alloc]init];
[user mts_setValuesForKeysWithDictionary:JSON]; // <-- Crash, because MOTIS try to set value to user_age, but User Class did't have property user_age
NSLog(@"%@", user.name);

Condition 2

Only implement mts_shouldSetUndefinedKeys

// User.m
@implementation User
+ (BOOL)mts_shouldSetUndefinedKeys
{
    return NO;
}
@end
User *user = [[User alloc]init];
[user mts_setValuesForKeysWithDictionary:JSON]; // <-- Won't Crash
NSLog(@"%@", user.name); // <-- null, same issue as #12

Condition 3

Implment both implement + mts_shouldSetUndefinedKeys, implement +mts_mapping

// User.m
@implementation User
+(NSDictionary *)mts_mapping
{
    return @{@"name" : mts_key(name)};
}

+ (BOOL)mts_shouldSetUndefinedKeys
{
    return NO;
}
@end
User *user = [[User alloc]init];
[user mts_setValuesForKeysWithDictionary:JSON]; // <-- Won't Crash
NSLog(@"%@", user.name); // <-- shinrenpan, but I need implement both + mts_shouldSetUndefinedKeys, implement +mts_mapping

I have no time to review all code but I have fixed issue in gist quickly, you can compare it.

It will works for Condition 1, 2, 3.

@vilanovi
Copy link
Contributor

Hello @shinrenpan ,

The behaviour that you have described is exactly what I have designed.

  • In condition 1 you will have crash because Motis is attempting to set a value for an undefined key. However, you can override the KVC method -setValue:forUndefinedKey: to remove the exception.
  • In condition 2 you will have a nil value because Motis doesn't have a defined mapping and you are forcing to ignore keys for undefined mappings. This is not an issue.
  • In condition 3 everything will work because you are defining a mapping. However, you are not forced to implement +mts_shouldSetUndefinedKeys. From Motis 0.4.6 the method +mts_shouldSetUndefinedKeys is returning YES if mts_mapping returns an empty dictionary and NO otherwise. So whenever you define a single entry in the mts_mapping, Motis will start filtering your JSON dictionaries.

Therefore, could you explain what are you solving in your gist? If you tell me what are you trying to achieve I can explain you how you should use Motis to handle it.

Thanks,

Joan

@shinrenpan
Copy link
Author

Hi @vilanovi

In condition 1, the User class has property name as same as JSON key name but without user_age.

I thought the Motis will automatically set value for User property name,
and automatically ignore set user_age, but I was wrong.

In my gist line 441, before the Motis set value for key, I implement that -
if the User class all properties or + mts_mapping all keys contain JSON key,
the Motis set the value, otherwise.

However, the developer who uses the Motis can override setValue: forUndefinedKey:
or override - mts_validateValue: forKey: error: to handle it.

But I think less code is better for developer who uses the Motis :)

@vilanovi
Copy link
Contributor

Hello @shinrenpan,

As you say, If your are receiving JSON that contains key-value pairs that your model objects are not handling you must perform one of the following two approaches in order to use Motis:

  1. Override the +mts_mapping and return a dictionary with a mapping for the desired keys (even if your dictionary contains the same key and values (exemple: @{"myKey":mts_key(myKey)}). No need of override the method +mts_shouldSetUndefinedKeys and make it return NO, as it is already returning NO by default.

  2. Do not override +mts_mapping and make your properties have the same name as your JSON keys. Override also the KVC method -setValue:forUndefinedKey: and just do nothing (by default this method throws an exception).

My personal suggestion is to do approach 1). You will be sure that you are redirecting the JSON key-value pairs to your desired properties. Also, because Motis is filtering your JSON containers, you will be sure that no "undesired JSON key-values pairs" are being set to any of your object properties or superclass object properties.

Currently, I really think that by using Motis to perform the JSON object mapping you are writing almost no code, and for those specific cases (as it happens to you) you only need to add a few lines more.

Please, do not hesitate to contact me again if you have any other problem.

Thanks, Joan

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants