Browse Source

Add custom transform method before the default json to model

Arron 9 năm trước cách đây
mục cha
commit
cf41f5e151

+ 13 - 0
YYModel/NSObject+YYModel.h

@@ -396,6 +396,19 @@ NS_ASSUME_NONNULL_BEGIN
  */
  */
 - (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic;
 - (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic;
 
 
+/**
+ This method's behavior is similar to `- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic;`, but be called before the model transform.
+ 
+ @discussion If the model implements this method, it will be called before
+ `+modelWithJSON:`, `+modelWithDictionary:`, `-modelSetWithJSON:` and `-modelSetWithDictionary:`.
+ If this method returns nil, the transform process will ignore this model.
+ 
+ @param dic  The json/kv dictionary.
+ 
+ @return Returns NSDictionary for change the json/kv dictionary, or nil to ignore this model.
+ */
+- (NSDictionary *)modelCustomWillTransformFromDictionary:(NSDictionary *)dic;
+
 /**
 /**
  If the default model-to-json transform does not fit to your model class, implement
  If the default model-to-json transform does not fit to your model class, implement
  this method to do additional process. You can also use this method to validate the
  this method to do additional process. You can also use this method to validate the

+ 12 - 1
YYModel/NSObject+YYModel.m

@@ -419,6 +419,8 @@ static force_inline id YYValueForMultiKeys(__unsafe_unretained NSDictionary *dic
     YYEncodingNSType _nsType;
     YYEncodingNSType _nsType;
     
     
     BOOL _hasCustomTransformFromDictionary;
     BOOL _hasCustomTransformFromDictionary;
+    BOOL _hasCustomWillTransformFromDictionary;
+
     BOOL _hasCustomTransformToDictionary;
     BOOL _hasCustomTransformToDictionary;
     BOOL _hasCustomClassFromDictionary;
     BOOL _hasCustomClassFromDictionary;
 }
 }
@@ -561,7 +563,8 @@ static force_inline id YYValueForMultiKeys(__unsafe_unretained NSDictionary *dic
     _hasCustomTransformFromDictionary = ([cls instancesRespondToSelector:@selector(modelCustomTransformFromDictionary:)]);
     _hasCustomTransformFromDictionary = ([cls instancesRespondToSelector:@selector(modelCustomTransformFromDictionary:)]);
     _hasCustomTransformToDictionary = ([cls instancesRespondToSelector:@selector(modelCustomTransformToDictionary:)]);
     _hasCustomTransformToDictionary = ([cls instancesRespondToSelector:@selector(modelCustomTransformToDictionary:)]);
     _hasCustomClassFromDictionary = ([cls respondsToSelector:@selector(modelCustomClassForDictionary:)]);
     _hasCustomClassFromDictionary = ([cls respondsToSelector:@selector(modelCustomClassForDictionary:)]);
-    
+    _hasCustomWillTransformFromDictionary = ([cls instancesRespondToSelector:@selector(modelCustomWillTransformFromDictionary:)]);
+
     return self;
     return self;
 }
 }
 
 
@@ -1422,13 +1425,21 @@ static NSString *ModelDescription(NSObject *model) {
     if (!dic || dic == (id)kCFNull) return NO;
     if (!dic || dic == (id)kCFNull) return NO;
     if (![dic isKindOfClass:[NSDictionary class]]) return NO;
     if (![dic isKindOfClass:[NSDictionary class]]) return NO;
     
     
+
     _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:object_getClass(self)];
     _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:object_getClass(self)];
     if (modelMeta->_keyMappedCount == 0) return NO;
     if (modelMeta->_keyMappedCount == 0) return NO;
+    
+    if (modelMeta->_hasCustomWillTransformFromDictionary) {
+        dic = [((id<YYModel>)self) modelCustomWillTransformFromDictionary:dic];
+        if (![dic isKindOfClass:[NSDictionary class]]) return NO;
+    }
+    
     ModelSetContext context = {0};
     ModelSetContext context = {0};
     context.modelMeta = (__bridge void *)(modelMeta);
     context.modelMeta = (__bridge void *)(modelMeta);
     context.model = (__bridge void *)(self);
     context.model = (__bridge void *)(self);
     context.dictionary = (__bridge void *)(dic);
     context.dictionary = (__bridge void *)(dic);
     
     
+    
     if (modelMeta->_keyMappedCount >= CFDictionaryGetCount((CFDictionaryRef)dic)) {
     if (modelMeta->_keyMappedCount >= CFDictionaryGetCount((CFDictionaryRef)dic)) {
         CFDictionaryApplyFunction((CFDictionaryRef)dic, ModelSetWithDictionaryFunction, &context);
         CFDictionaryApplyFunction((CFDictionaryRef)dic, ModelSetWithDictionaryFunction, &context);
         if (modelMeta->_keyPathPropertyMetas) {
         if (modelMeta->_keyPathPropertyMetas) {

+ 17 - 0
YYModelTests/YYTestCustomTransform.m

@@ -20,6 +20,18 @@
 
 
 @implementation YYTestCustomTransformModel
 @implementation YYTestCustomTransformModel
 
 
+
+-(NSDictionary *)modelCustomWillTransformFromDictionary:(NSDictionary *)dic{
+    if (dic) {
+        NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:dic];
+        if (dict[@"date"]) {
+            dict[@"time"] = dict[@"date"];
+        }
+        return dict;
+    }
+    return dic;
+}
+
 - (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic {
 - (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic {
     NSNumber *time = dic[@"time"];
     NSNumber *time = dic[@"time"];
     if ([time isKindOfClass:[NSNumber class]] && time.unsignedLongLongValue != 0) {
     if ([time isKindOfClass:[NSNumber class]] && time.unsignedLongLongValue != 0) {
@@ -74,6 +86,11 @@
     model.time = nil;
     model.time = nil;
     jsonObject = [model yy_modelToJSONObject];
     jsonObject = [model yy_modelToJSONObject];
     XCTAssert(jsonObject == nil);
     XCTAssert(jsonObject == nil);
+    
+    json = @"{\"id\":5472746497,\"content\":\"Hello\",\"date\":1401234567000}";
+    model = [YYTestCustomTransformModel yy_modelWithJSON:json];
+    XCTAssert(model.time != nil);
+    
 }
 }
 
 
 @end
 @end