2013-09-21 3 views
8

JSON 응답에 기본 객체 만 포함되고 완전히 중첩 된 배열이 없으면 새 객체를 만들 때 관계를 매핑하는 데 문제가 있습니다.기본 키가있는 RestKit 관계 매핑

저는 Shop과 Item의 2 개의 클래스가 있으며, Shop-> Item은 일대 다 관계가 있습니다.

기본 키가있는 상점 (및 항목)의 로컬 코어 데이터 저장소가 있습니다. 그런 다음 항목 목록을 JSON으로 다운로드하고 핵심 데이터 엔티티에 매핑하려고하지만 모든 상점 세부 정보가 중첩 배열이 아닌 샵의 기본 키만 포함하려는 경우 - 이것은 네트워크 트래픽의 막대한 낭비입니다. 500 개 이상의 항목을 다운로드 중입니다.

/상점

{ 
    "id" : 1, 
    "shop" : "Shop A", 
    "city" : "New York" 
}, 
{ 
    "id" : 2, 
    "shop" : "Shop B", 
    "city" : "London" 
}, 
... 

/항목 다음

{ 
    "id" : 1, 
    "name" : "Shoes", 
    "manufacturer" : "Vans", 
    "shopId" : 1 
}, 
{ 
    "id" : 2, 
    "name" : "T-shirt", 
    "manufacturer" : "Animal", 
    "shopId" : 2 
}, 
{ 
    "id" : 3, 
    "name" : "Scarf", 
    "manufacturer" : "Ted Baker", 
    "shopId" : 1 
}, 
{ 
    "id" : 4, 
    "name" : "Sunglasses", 
    "manufacturer" : "Ray-Ban", 
    "shopId" : 3 
}, 
... 

내 코드는 순간입니다 : 여기

는이 개 요청에서 JSON입니다 .

AppDelegate.m

... 

NSURL *baseURL = [NSURL URLWithString:@"http://localhost/company/API"]; 
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseURL]; 

[AFNetworkActivityIndicatorManager sharedManager].enabled = YES; 

[objectManager.HTTPClient setDefaultHeader:@"Accept" value:@"application/json"]; 

NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil]; 
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel]; 
objectManager.managedObjectStore = managedObjectStore; 

// Shop Mapping 

RKEntityMapping *shopMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Shop class]) 
                 inManagedObjectStore:objectManager.managedObjectStore]; 
NSDictionary *shopMappingAttributes = [NSDictionary dictionaryWithObjectsAndKeys:@"objectId",@"id",@"name",@"shop",@"city",@"city",nil]; 
shopMapping.identificationAttributes = @[@"objectId"]; 
[shopMapping addAttributeMappingsFromDictionary:shopMappingAttributes]; 
[objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:shopMapping 
                      pathPattern:@"/shops" 
                       keyPath:nil 
                      statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]; 


// Item Mapping 

RKEntityMapping *itemMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Item class]) 
                 inManagedObjectStore:objectManager.managedObjectStore]; 
NSDictionary *itemMappingAttributes = [NSDictionary dictionaryWithObjectsAndKeys:@"objectId",@"id",@"name", @"name",@"manufacturer",@"manufacturer",nil]; 
itemMapping.identificationAttributes = @[@"objectId"]; 
[itemMapping addAttributeMappingsFromDictionary:itemMappingAttributes]; 

// Define the relationship mapping 

[objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:itemMapping 
                      pathPattern:@"/items" 
                       keyPath:nil 
                      statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]; 

... 

ItemsTableViewController.m

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    // Update Shops 
    [[RKObjectManager sharedManager] getObjectsAtPath:@"/shops" 
             parameters:nil 
              success:nil 
              failure:^(RKObjectRequestOperation *operation, NSError *error) { 
               NSLog(@"Error: %@",error); 
              }]; 

    // Update/Get Items 
    NSDictionary *parameters = @{ 
          @"username": self.username, 
          @"password": self.password, 
          @"API_key": @"abc123", 
          }; 

    NSMutableURLRequest *request = [[RKObjectManager sharedManager] requestWithObject:nil 
                      method:RKRequestMethodPOST 
                      path:@"/items" 
                     parameters:parameters]; 

    RKManagedObjectRequestOperation *operation = [[RKObjectManager sharedManager] managedObjectRequestOperationWithRequest:request managedObjectContext:[RKManagedObjectStore defaultStore].mainQueueManagedObjectContext 
                    success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { 
                     Item *item = [mappingResult firstObject]; 
                     NSLog(@"Mapped the Item: %@", item); 
                    } failure:^(RKObjectRequestOperation *operation, NSError *error) { 
                     NSLog(@"Error: %@",error); 
                    }]; 
    NSOperationQueue *operationQueue = [NSOperationQueue new]; 
    [operationQueue addOperation:operation]; 
} 

편집 : 북두칠성, 내가 가진 응용 프로그램 위임의 관련 장소에서이 있지만, 내가 놓친 무엇 NSException

NSEntityDescription *itemEntity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:managedObjectStore.mainQueueManagedObjectContext]; 
NSRelationshipDescription *shopRelationship = [itemEntity relationshipsByName][@"shop"]; 
RKConnectionDescription *connection = [[RKConnectionDescription alloc] initWithRelationship:shopRelationship attributes:@{ @"shopId": @"objectId" }]; 
[itemMapping addConnection:connection]; 

NSException

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name 'Item'' 

를 얻을?

답변

5

항목에 임시 속성 (shopId)과 관련 매핑을 추가해야합니다.

구성으로 외래 키 매핑을 사용하여 관계 :

NSEntityDescription *itemEntity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:managedObjectContext]; 
NSRelationshipDescription *shopRelationship = [itemEntity relationshipsByName][@"shop"]; 
RKConnectionDescription *connection = [[RKConnectionDescription alloc] initWithRelationship:shopRelationship attributes:@{ @"shopId": @"id" }]; 

그런 다음 당신의 매핑에 추가 addConnection:를 사용합니다.

+0

감사합니다. @Wain. 이 코드 스 니펫은 App Delegate 또는 View Controller에 있습니까? Andy – Andy

+0

이전에 관계 매핑을 추가하려고 시도했지만 (중첩 된 항목의 경우) 'itemMapping'에 추가하십시오. – Wain

+0

예외가 발생했습니다. 편집을 참조하십시오. Item에 일시적인 속성을 만들지 않았기 때문에이 작업이 수행됩니까? 그렇다면 어떻게? Andy – Andy