2012-08-02 53 views
3

假設在我的數據模型中,我有Pages,其中有許多CommentsRestKit:連接不在響應中的關係

我想連接模型中的一個關係,該關係從Comment返回到它所屬的Page,但Page對象不嵌套在響應中,也沒有任何可以標識父頁面的主鍵出現在回覆中。

當我撥打loadObjectsAtResourcePath時,加載的所有Comments都應該屬於固定的已知Page對象。我可以掛鉤的關係的一種方式是做:

loader.onDidLoadObjects = ^(NSArray* objs) { 
    for (Comment* comment in objs) comment.page = self.page; 
    ... 
} 

但我希望有一個更好的辦法。請注意,我不能使用connectRelationship系列方法,因爲響應中沒有主鍵,可以讓我將每個Comment都掛鉤到Page

回答

2

您可以使用委託方法- (void)objectLoader:(RKObjectLoader *)loader willMapData:(inout id *)mappableData在映射步驟之前注入額外的參數。它確保在使用核心數據時,RestKit可以正確保存對象和關係(請注意,上面給出的解決方案不會保存關係)。

或者,看看this答案,我展示瞭如何覆蓋RKObjectLoader以從URL本身檢索頁面信息。

編輯:這是我在評論中提到的類別:

.H

#import <RestKit/RestKit.h> 

typedef void(^RKObjectLoaderWillMapDataBlock)(id* mappableData); 

@interface RKObjectLoader (Extended) 

@property (nonatomic, copy) RKObjectLoaderWillMapDataBlock onWillMapData; 

@end 

與.m:

#import <objc/runtime.h> 

NSString* kOnWillMapDataKey = @"onWillMapData"; 

@implementation RKObjectLoader (Extended) 

- (RKObjectLoaderWillMapDataBlock) onWillMapData { 
    return objc_getAssociatedObject(self, &kOnWillMapDataKey); 
} 

- (void) setOnWillMapData:(RKObjectLoaderWillMapDataBlock) block { 
    objc_setAssociatedObject(self, &kOnWillMapDataKey, block, OBJC_ASSOCIATION_COPY); 
} 

- (RKObjectMappingResult*)mapResponseWithMappingProvider:(RKObjectMappingProvider*)mappingProvider toObject:(id)targetObject inContext:(RKObjectMappingProviderContext)context error:(NSError**)error { 
    id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType:self.response.MIMEType]; 
    NSAssert1(parser, @"Cannot perform object load without a parser for MIME Type '%@'", self.response.MIMEType); 

    // Check that there is actually content in the response body for mapping. It is possible to get back a 200 response 
    // with the appropriate MIME Type with no content (such as for a successful PUT or DELETE). Make sure we don't generate an error 
    // in these cases 
    id bodyAsString = [self.response bodyAsString]; 
    RKLogTrace(@"bodyAsString: %@", bodyAsString); 
    if (bodyAsString == nil || [[bodyAsString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) { 
     RKLogDebug(@"Mapping attempted on empty response body..."); 
     if (self.targetObject) { 
      return [RKObjectMappingResult mappingResultWithDictionary:[NSDictionary dictionaryWithObject:self.targetObject forKey:@""]]; 
     } 

     return [RKObjectMappingResult mappingResultWithDictionary:[NSDictionary dictionary]]; 
    } 

    id parsedData = [parser objectFromString:bodyAsString error:error]; 
    if (parsedData == nil && error) { 
     return nil; 
    } 

    // Allow the delegate to manipulate the data 
    if ([self.delegate respondsToSelector:@selector(objectLoader:willMapData:)]) { 
     parsedData = [parsedData mutableCopy]; 
     [(NSObject<RKObjectLoaderDelegate>*)self.delegate objectLoader:self willMapData:&parsedData]; 
    } 

    if(self.onWillMapData) { 
     parsedData = [parsedData mutableCopy]; 
     self.onWillMapData(&parsedData); 
    } 

    RKObjectMapper* mapper = [RKObjectMapper mapperWithObject:parsedData mappingProvider:mappingProvider]; 
    mapper.targetObject = targetObject; 
    mapper.delegate = (id<RKObjectMapperDelegate>)self; 
    mapper.context = context; 
    RKObjectMappingResult* result = [mapper performMapping]; 

    // Log any mapping errors 
    if (mapper.errorCount > 0) { 
     RKLogError(@"Encountered errors during mapping: %@", [[mapper.errors valueForKey:@"localizedDescription"] componentsJoinedByString:@", "]); 
    } 

    // The object mapper will return a nil result if mapping failed 
    if (nil == result) { 
     // TODO: Construct a composite error that wraps up all the other errors. Should probably make it performMapping:&error when we have this? 
     if (error) *error = [mapper.errors lastObject]; 
     return nil; 
    } 

    return result; 
} 

@end 
+0

'objectLoader:willMapData:'和'connectRelationship一起:...是一個很好的解決方案。 RestKit非常棒,我想我們可以通過記錄服務器響應時間不符合其假設的解決方案,使它更加有用。 – jogloran 2012-08-03 09:27:07

+0

爲什麼'RKObjectLoader'上沒有'willMapData'的塊版本,就像'onDidLoadObjects'和其他塊參數一樣? – HiveHicks 2012-08-17 12:43:56

+1

不知道。我有一個可以在這裏發佈的類別,但是在另一臺計算機上還需要幾天。 – 2012-08-17 19:56:22