2016-06-18 17 views
0
私は Restkitと、次のJSONレスポンスをマップしようとしている

"value"内部の構造が動的であるRestkitネストされたオブジェクトのマッピング奇妙な問題

{ 
    "container": { 
    "id": 1, 
    "infos": [ 
     { 
     "id": 1, 
     "name": "...", 
     "type": 6, 
     "value": { 
      "d0": { 
      "periods": [ 
       { "close": "12.30", "open": "09.00" }, 
       { "close": "19.30", "open": "15.30" } 
      ] 
      }, 
      "d1": {...}, 
      "d2": {...}, 
      "d3": {...}, 
      "d4": {...}, 
      "d5": {...}, 
      "d6": {...} 
     }, 
     "created": "2015-12-08T17:18:05.732Z", 
     } 
    ] 
    } 
} 

- それは、応答のタイプに応じて変えることができていますAPIによって返されます。

@interface CFFContainer : NSObject 
@property (nonatomic, retain) NSNumber *identifier; 
@property (nonatomic, retain) NSMutableArray *infos; 
@end 

@interface CFFInfo : NSObject 
@property (nonatomic, retain) NSNumber *identifier; 
@property (nonatomic, retain) NSString *name; 
@property (nonatomic, retain) NSNumber *type; 
@property (nonatomic, retain) NSMutableDictionary *value; 
@property (nonatomic, retain) NSDate *created; 
@end 

@interface CFFOpeningTimes : NSObject 
@property (nonatomic, retain) CFFOpeningDay *d0; 
@property (nonatomic, retain) CFFOpeningDay *d1; 
@property (nonatomic, retain) CFFOpeningDay *d2; 
@property (nonatomic, retain) CFFOpeningDay *d3; 
@property (nonatomic, retain) CFFOpeningDay *d4; 
@property (nonatomic, retain) CFFOpeningDay *d5; 
@property (nonatomic, retain) CFFOpeningDay *d6; 
@end 

@interface CFFOpeningDay : NSObject 
@property (nonatomic, retain) NSMutableArray *periods; 
@end 

@interface CFFPeriod : NSObject 
@property(nonatomic, retain) NSString *open; 
@property(nonatomic, retain) NSString *close; 
@end 

(私はCFFInfo.valueための汎用NSMutableDictionaryを使用できるかどうかわからないが、私は、エンティティの実際のものと構造を知らないので、私は、特定のタイプを割り当てることはできませんが、次のように実装されたオブジェクトのクラスがありますされます)。 そして最後にマッピング:

// Container. 
[containerMapping addAttributeMappingsFromDictionary:@{@"identifier": @"id"}]; 
RKRelationshipMapping *infoMapping = 
[RKRelationshipMapping relationshipMappingFromKeyPath:@"infos" 
              toKeyPath:@"infos" 
              withMapping:[CFFInfo mapping]]; 
[responseMapping addPropertyMapping:infoMapping]; 

// Info. 
[infoMapping addAttributeMappingsFromDictionary:@{@"identifier": @"id", @"name": @"name", @"type": @"type", @"created": @"created"}]; 

// Create dynamic mapping for surveys, opening times, news, etc.  
RKDynamicMapping *dynamicMapping = [[RKDynamicMapping alloc] init]; 
[dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) { 
    if ([[representation valueForKey:@"name"] containsString:@"Survey"]) { 
     return [CFFSurvey mapping]; 
    } else if ([representation valueForKey:@"d0"] != nil) { 
     return [CFFOpeningTimes mapping]; 
    } else if ([[representation valueForKey:@"name"] containsString:@"News"]) { 
     return [CFFNews mapping]; 
    } 
    return nil; 
}]; 

RKRelationshipMapping *valueMapping = 
[RKRelationshipMapping relationshipMappingFromKeyPath:@"value" 
              toKeyPath:@"value" 
              withMapping:dynamicMapping]; 
[infoMapping addPropertyMapping: valueMapping]; 

// Opening times. 
RKRelationshipMapping * d0mapping = 
[RKRelationshipMapping relationshipMappingFromKeyPath:@"d0" 
              toKeyPath:@"d0" 
              withMapping:[CFFOpeningDay mapping]]; 
[openingTimesMapping addPropertyMapping:d0mapping]; 
// ... same for d1, d2, d3, d4, d5, d6... 

// Opening day. 
RKRelationshipMapping *periodsMapping = 
[RKRelationshipMapping relationshipMappingFromKeyPath:@"periods" 
              toKeyPath:@"periods" 
              withMapping:[CFFPeriod mapping]]; 
[periodMapping addPropertyMapping:periodsMapping]; 

// Period. 
[periodMapping addAttributeMappingsFromDictionary:@{@"open": @"open", @"close": @"close"}]; 

すべてのマッピング操作はスムーズに実行されますが、ログはすべてのエンティティの一致を示しているが、最終的に私は0キー/値のペアでcontainer.infos[0].valueオブジェクトを取得します。ログは実際に言う:

restkit.object_mapping:RKMappingOperation.m:887 
Mapped relationship object from keyPath 'value' to 'value'. 
Value: <CFFOpeningTimes: 0x796eb6d0> 

奇妙なことは、異なる動的マッピングがvalueに適用されている場合(例えば[CFFSurvey mapping])マッピングされたオブジェクトは、正しいデータが含まれていることです。私はまた、マッピング操作の実行をデバッグしようとしましたが、私が見る限りではmapNestedObject:toObject:parent:withRelationshipMapping:metadataList:メソッドRKMappingOperation.m - 行883は、戻された宛先オブジェクトにマップされたネストされたオブジェクトをコピーしないようです。

私は本当にこれについて怒っています。問題がどこにあるのかについてのアイデアはありますか?

答えて

0

私は問題が何かを発見しました。私が指摘したように、CFFInfo.valueNSMutableDictionaryのタイプは、明らかにそれにマップされる可能性のある一般的な構造に準拠していません。

だから私はそのタイプをより一般的なNSObject<NSCopying>に置き換えました。

@interface CFFInfo : NSObject 
@property (nonatomic, retain) NSNumber *identifier; 
@property (nonatomic, retain) NSString *name; 
@property (nonatomic, retain) NSNumber *type; 
@property (nonatomic, retain) NSObject<NSCopying> *value; 
@property (nonatomic, retain) NSDate *created; 
@end 

IはNSCopyingプロトコルを添加し、そのオブジェクトのコピーが必要な場合には、すべてのデータが正しくコピーされる保証するために、CFFOpeningTimesクラスとカスケードに使用されるクラスのためcopyWithZone:方法を実施しました。