2013-09-21 18 views
8

JSONレスポンスにプライマリキーのみが含まれ、新しいオブジェクトを作成する完全にネストされた配列が含まれていない場合、リレーションシップのマッピングに問題があります。RestKitプライマリキーを使用したリレーションシップマッピング

私は2つのクラス - ショップとアイテムを持っていますが、ショップ - >アイテムには1対多の関係があります。

私は、主キーを持つショップ(およびアイテム)のローカルコアデータストアを持っています。次に、JSONとしてItemのリストをダウンロードし、コアデータエンティティにマップしたいが、ネストされた配列としてすべてのショップの詳細を含むわけではない。 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は2つの要求からです。

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]; 
} 

EDIT: ウェイン、私が持っていますアプリデリゲートの関連する代わりに、この私が見逃している何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

関連する問題