2014-02-10 50 views
1

我正試圖在我的應用程序中映射JSON數組。我面臨的問題是不是獲取NSString類型的對象,而是獲取對象鍵入RKMappingSourceObject。Restkit 0.2返回RKMappingSourceObject類型用於一對多關係的對象

響應的形式是

{ 
     message =  { 
      Appetite =   { 
        Breakfast = 4; 
        Dinner = 4; 
        Lunch = 4; 
       }; 
     PainSymptom =   { 
     Aching = 1; 
       AtRest = 0; 
       Awakes = 0; 
       Burning = 0; 
       Cramping = 0; 
        Location =    (
         Head, 
         "Right Upper Leg", 
         "Left Upper Leg", 
         "Left Ankle/Foot", 
         "Right Ankle/Foot", 
         "Mid Back", 
         "Upper Back", 
         Tailbone 
        ); 
       }; 
     } 
} 

我的核心數據類是:

DTAttribute.h

@interface DTAttribute : NSManagedObject 

@property (nonatomic, strong) NSString * attribute; 
@property (nonatomic, strong) DTPainSymptom *painSymptom; 

@end 

DTAttribute.m

@implementation DTAttribute 

@dynamic attribute; 
@dynamic painSymptom; 

@end 

DTPainSymptom.h

@interface DTPainSymptom : NSManagedObject 

@property (nonatomic, retain) NSNumber * aching; 
@property (nonatomic, retain) NSNumber * atRest; 
@property (nonatomic, retain) NSNumber * awakes; 
@property (nonatomic, retain) NSNumber * burning; 
@property (nonatomic, retain) NSNumber * cramping; 
@property (nonatomic, retain) DTMyDay *myDay; 
@property (nonatomic, retain) NSSet *painLocations; 
@end 

@interface DTPainSymptom (CoreDataGeneratedAccessors) 

- (void)addPainLocationsObject:(DTAttribute *)value; 
- (void)removePainLocationsObject:(DTAttribute *)value; 
- (void)addPainLocations:(NSSet *)values; 
- (void)removePainLocations:(NSSet *)values; 

@end 

DTPainSymptom.m

@implementation DTPainSymptom 

@dynamic aching; 
@dynamic atRest; 
@dynamic awakes; 
@dynamic burning; 
@dynamic cramping; 
@dynamic myDay; 
@dynamic painLocations; 

@end 

DTMyDay.h

@interface DTMyDay : NSManagedObject 

@property (nonatomic, retain) DTPainSymptom *painSymptom; 

@end 

DTMyDay.m

@implementation DTMyDay 

@dynamic painSymptom; 

@end 

映射:

@implementation DTMyDay(映射)

+ (id) mapping { 
    RKEntityMapping* myDayMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([DTMyDay class]) inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]]; 

    RKEntityMapping* attributeMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([DTAttribute class]) inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]]; 
    [attributeMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"attribute"]]; 

    //Pain Symptom 
    RKEntityMapping* painSymptomMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([DTPainSymptom class]) inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]]; 
    [painSymptomMapping addAttributeMappingsFromDictionary:@{ 
                  @"Awakes": @"awakes", 
                  @"AtRest": @"atRest", 
                  @"Burning": @"burning", 
                  @"Cramping": @"cramping", 
                  @"Aching": @"aching", 
                  }]; 
    [painSymptomMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"Location" 
                        toKeyPath:@"painLocations" 
                        withMapping:attributeMapping]]; 


    [myDayMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"message.PainSymptom" 
                       toKeyPath:@"painSymptom" 
                      withMapping:painSymptomMapping]]; 

    NSDateFormatter* dateFormatter = [NSDateFormatter new]; 
    [dateFormatter setDateFormat:@"yyyy-MM-dd"]; 
    myDayMapping.dateFormatters = [NSArray arrayWithObject: dateFormatter]; 
    return myDayMapping; 
} 


+ (id)responseDescriptor:(NSString *)pathPattern { 
    RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[self mapping] pathPattern:pathPattern keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; 
    return responseDescriptor; 
} 

@end 

這裏的問題是對應於message.PainSymptom.Location值的陣列不正確映射。我在DTMyDay類中獲得對應於painLocations的DTAttribute類型對象的數組。但是,當我試圖訪問painLocations數組中的每個DTAttribute類的屬性屬性時,我得到RkMappingSourceObject類型的對象而不是NSString類型的對象。

我很抱歉代碼這個巨大的牆,但現在我真的不知道該怎麼做。

enter image description here

這使我一個問題,因爲我送dtAttribute.attribute一種方法,它返回我NSNotFound因爲傳遞的對象是類型RKMappingSourceObject的:

#define BODY_PARTS_NAMES @"Head", @"Right Shoulder", @"Neck", @"Left Shoulder", @"Right Chest", @"Left Chest", @"Right Arm", nil 

- (BodyPart)bodyPartStringToEnum:(NSString *)strVal 
{ 
    NSArray *bodyPartsArray = [[NSArray alloc] initWithObjects:BODY_PARTS_NAMES]; 
    NSUInteger index = [bodyPartsArray indexOfObject:strVal]; 

    return index; 
} 
+0

RKMappingSourceObject代理類會導致什麼問題?它只是將所有的方法調用轉發給真實的對象。你是否試圖在某處使用字符串描述(與你期望的相比,這看起來很奇怪)? – Wain

+0

我有一個函數,它需要一個NSString參數並返回給我一些值。當我向它發送dtAttribute.attribute時,它會返回我NSNotFound,因爲傳遞的對象是RKMappingSourceObject類型。 – tek3

+0

您可以將該方法的代碼添加到您的問題中,我們將着手修復它嗎? – Wain

回答

0

RKMappingSourceObject是一個代理對象在RestKit中用於處理映射過程中的內省問題和元數據。由於它是一個代理,並轉發所有方法調用,它只是在映射結束時返回。通常這不會導致問題。

我沒有想到它會根據您的代碼導致問題,但顯然比較方法中的某些內容不起作用。 RKMappingSourceObject應該轉發兩種class請求和「正常」的方法調用...

RKMappingSourceObjectobject方法,問題是如何知道你應該把它(因爲類應爲NSString一些子類返回) 。我想看看一個討厭的東西,如:

- (BodyPart)bodyPartStringToEnum:(NSString *)strVal 
{ 
    if ([strVal respondsToSelector:@selector(object)]) { 
     strVal = [strVal object]; 
    } 

    NSArray *bodyPartsArray = [[NSArray alloc] initWithObjects:BODY_PARTS_NAMES]; 
    NSUInteger index = [bodyPartsArray indexOfObject:strVal]; 

    return index; 
} 

,我不喜歡,但希望將工作和與以(去除)在未來的代理對象的潛在變化兼容。或者,調試以確定比較失敗的原因並查看更改代理實現。

+0

我想到了你的解決方法,現在我只是這樣做。但是我在代碼中的其他地方遇到了問題,在該代碼中,我使用NSPredicate對值屬性過濾了painSymptom.painLocations(DTAttribute的NSSet)集。它無法過濾該設置。 – tek3

+1

因此,您可以將該代碼移動到自定義訪問器方法實現中(因此它總是用於訪問來自代理的「對象」)。我很想知道爲什麼代理不工作,調試是最好的方式。可能有替代方案使用'copy'從代理創建一個新的字符串(可能在託管對象的子類中)。 – Wain

0

轉換RKMappingSourceObjectNSString的另一種方法:

NSString *realString = [NSString stringWithString:stringProxy]; 

其中stringProxyRKMappingSourceObject一個實例。