Conversation
fe0b04e to
20f0098
Compare
|
Looks awesome, i'm also going to use this. |
|
I'm sorry, I don't understand. Do this PR solve the problem below? @interface BaseModel : NSObject
@property (nonatomic) NSString *property1; // There are more properties
@interface BaseModelForApi1 : BaseModel
@end
@interface BaseModelForApi2 : BaseModel
@end
@implementation BaseModelForApi1
+ (JSONKeyMapper)keyMapper
{
return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:@{@"property1":@"api_1_field"}];
}
@end
@implementation BaseModelForApi2
+ (JSONKeyMapper)keyMapper
{
return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:@{@"property1":@"api_2_field"}];
}
@endThe key point is to map one property to more than one different keys ? |
|
I think Multiple KeyMappers may be the best solution to #545 and #612, not Single KeyMapper play as multiple roles, taking Expansibility and Dependency Inversion into consideration. The best situation should be only one JSONModel Class with multiple KeyMappers, not a JSONModel Cluster. |
|
I'm sorry for my poor comments above. I think you are right: One model with multiple KeyMappers will meet problem with nested models. But I still don't understand. How does the method work for this issue ? How can you make your decision with the case blow: api1: {
"orderId": 104,
"totalPrice": 13.45,
"product": {
"id": 123,
"name": "Product name",
"price": 12.95
}
}api 2: {
"orderId": 104,
"totalPrice": 13.45,
"product": {
"product_id": 123,
"name": "Product name",
"price": 12.95
}
}@interface ProductModel : JSONModel
@property (nonatomic) NSInteger id;
@property (nonatomic) NSString *name;
@property (nonatomic) float price;
@end
@interface ProductModelApi1 : ProductModel
@end
@interface ProductModelApi2 : ProductModel
@end
@interface OrderModel : JSONModel
@property (nonatomic) NSInteger orderId;
@property (nonatomic) float totalPrice;
@property (nonatomic) ProductModel *product;
@end |
|
This enables the issue to be resolved, to some degree, by enabling the keymapper to act differently based on the context of the class. I agree it isn't a great solution, but to be honest I'm not sure what else we can do here. Do you have any other suggestions? |
|
@billinghamj Glad with your reply :) I'm sorry I can not help a lot currently, I'm still thinking about it. The word "context" you have mentioned above is quite close. The hardest part of solution is delivering the "context" through out the entire conversion. @interface ProductModel : JSONModel
@property (nonatomic) NSInteger id;
@property (nonatomic) NSString *name;
@property (nonatomic) float price;
@end
@interface ProductModelApi1 : ProductModel
@end
@interface ProductModelApi2 : ProductModel
@end
@interface OrderModel : JSONModel
@property (nonatomic) NSInteger orderId;
@property (nonatomic) float totalPrice;
@property (nonatomic) ProductModel *product;
@endWhen we call [OrderModel toDictionary], the "context" will be lost in [ProductModel toDictionary] stage. I'm poor in Android, but I've heard that there is a "context" technology, which can be access through out some entire process. I think the "context" design could be helpful to our issue. It's hard to say in words. The solution must be in higher dimensionality, not under. And If the "context" can be access through out, multithreading must be taken into consideration. |
|
Class cluster should not be invited, since it will lead things complexing. When invited, there must be some code to copy ProductModelApi2 from ProductModelApi1. Thus there will be multi set of models. AClassApi1 AClassApi2 BClassApi1 BClassApi2 ... XClassApi1 XClassApi2. I'd like to introduce some code, which could be inspired : // Default Context
OrderModel *orderModel;
NSDictionary *dict = [orderModel toDictionary];
// Default Context End
// Context Api2
[JSONModelContext startNewContextWithIdentifier:@"Api2"];
NSDictionary *dict = [orderModel toDictionary];
[JSONModelContext endContext];
// Context Api2 EndThere is only one set of model classes, and one key mapper for each. But we can enable key mapper to behave differently when it is under custom context than the default context. |
|
Or we just bind the context with root instance, and the context will be passed on through out the entire serialization. Since global context will met problem with multi threading // Default Context
OrderModel *orderModel;
NSDictionary *dict = [orderModel toDictionary];
// Context Api2
JSONModelContext *api2Context [JSONModelContext contextWithIdentifier:@"Api2"];
NSDictionary *dict = [orderModel toDictionaryWithContext:api2Context]; |
|
I have previously considered a method like I like the idea of being able to say MyModel *obj = [[MyModel alloc] initWithData:data options:@{@"style":"snake_case"}];
[obj toDictionaryWithOptions:@{@"style":"camel_case"}];The meaning of the options dictionary would be entirely up to the application developer - they’d just receive it back as-is in some methods. This would replace the class input on the keymappers in this PR. (Though would anyone potentially still want the class, in addition?) |
|
It seems great ! The options dictionary, which plays a role as context, will be delivered to every key mapper in the conversion chain. |
No description provided.