Ho problemi a mappare le relazioni quando la risposta JSON contiene solo la chiave primaria e non una matrice completamente nidificata per creare il nuovo oggetto.Mapping relazioni RestKit con chiave primaria
Ho 2 classi - Negozio e oggetto, e come ci si aspetterebbe che l'articolo Shop-> Item abbia una relazione uno-a-molti.
Ho un archivio locale di dati di base di negozi (e articoli), ciascuno con una chiave primaria. Vorrei quindi scaricare un elenco di elementi come JSON e mappare a entità di dati di base, ma includere solo la chiave primaria del negozio, e non tutti i dettagli del negozio come un array annidato - questo sarebbe un enorme spreco di traffico di rete mentre Sto scaricando i dettagli di oltre 500 articoli.
Ecco la JSON dai due richieste:
/negozi
{
"id" : 1,
"shop" : "Shop A",
"city" : "New York"
},
{
"id" : 2,
"shop" : "Shop B",
"city" : "London"
},
...
/articoli
{
"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
},
...
Ecco il mio codice in questo momento .
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: Wain, ho questo nel posto di rilievo nel delegato app, ma ottenere un 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''
Che cosa ho mancato?
grazie a @Wain. Questo snippet di codice andrebbe nel Delegato app o nel controller di visualizzazione? Andy – Andy
Aggiungilo a 'itemMapping' dove in precedenza hai provato ad aggiungere un mapping delle relazioni (ma per un elemento annidato). – Wain
Ricevo un'eccezione: vedi modifica. È perché non ho creato l'attributo transitorio sull'elemento? Se é cosi, come? Andy – Andy