I would create three entities, Supermarket, Product and SupermaketProductDetails, with attributes and relationships as follows:
Supermarket:
Attributes: name, location, phone number
Relationship (to many): productDetails
Product:
Attributes: name, price, company
Relationship (to many): supermarketDetails
SupermarketProductDetails:
Attributes: priceofProductforGivenMarket, primaryProductforGivenMarket
Relationships: (to one) supermarket, (to one) product
In Xcode, indicate that the "destination" for the productDetails relationship in the Supermarket entity is the SupermarketProductDetails entity, with inverse supermarket, likewise set the SupermarketProductDetails entity as the destination for the supermarketDetails in the Product entity, with inverse product.
Then I would parse your JSON data for supermarkets first, creating Supermarket objects and setting the name, location and phone number but without entering anything for the products relationship. Likewise, parse the products JSON and create all the Products objects. Then I would parse the join table, and create the SupermarketProductDetails objects. Set the attributes based on your JSON data, and execute a fetch to get the Supermarket entity with the right name, likewise fetch the Product entity with the right name, and then set these relationships directly.
EDIT:
Assume that you parse each line in your join table into four NSStrings: nameofsupermarket, nameofproduct, priceofProductforGivenMarket and primaryProductforGivenMarket. Then for each line...
// First fetch the correct Supermarket...
NSFetchRequest *supermarketFetch = [NSFetchRequest fetchRequestWithEntityName:@"Supermarket"]
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@",nameofsupermarket];
supermarketFetch.predicate = predicate;
NSError *error;
NSArray *results = [context executeFetchRequest:supermarketFetch error:&error];
// should really check for errors, and that we get one and only one supermarket
NSLog(@"Supermarket fetch returned %i results",[results count]); // should be only 1!
mySupermarket = (NSManagedObject *)[results firstObject];
if (![[mySupermarket valueForKey:@"name"] isEqualToString:nameofsupermarket]) {
NSLog(@"Wrong supermarket fetched");
}
// Now fetch the product...
NSFetchRequest *productFetch = [NSFetchRequest fetchRequestWithEntityName:@"Product"]
predicate = [NSPredicate predicateWithFormat:@"name like %@",nameofproduct];
productFetch.predicate = predicate;
results = [context executeFetchRequest:productFetch error:&error];
// should really check for errors, and that we get one and only one product
NSLog(@"Product fetch returned %i results",[results count]); // should be only 1!
myProduct = (NSManagedObject *)[results firstObject];
if (![[myProduct valueForKey:@"name"] isEqualToString:nameofproduct]) {
NSLog(@"Wrong product fetched");
}
// Now create the SupermarketProductDetails entity:
NSManagedObject *mySupermarketProductDetails = [NSEntityDescription insertNewObjectForEntityForName:@"SupermarketProductDetails" inManagedObjectContext:context];
// set attributes...
[mySupermarketProductDetails setValue:primaryProductForGivenMarket forKey:@"primaryProductForGivenMarket"];
[mySupermarketProductDetails setValue:priceOfProductForGivenMarket forKey:@"priceOfProductForGivenMarket"];
// set relationships...
[mySupermarketProductDetails setValue:mySupermarket forKey:@"supermarket"];
[mySupermarketProductDetails setValue:myProduct forKey:@"product"];
[context save:&error];
// should check for errors...
Note that you only need to set one side of these relationships - CoreData updates the other side for you (i.e. it will add mySupermarketDetails to the set of supermarketDetails for myProduct, etc). Note also that the "value" for a (to-one) relationship (e.g. supermarket) is the destination object itself (e.g. mySupermarket); you don't use the name or any other key. Coredata is (hidden in the underlying sql tables) using unique objectIDs to do the linking up.
(There are probably more efficient means of doing this, rather than doing two fetches for every SupermarketProductDetails entry, but this will work.)
EDIT2: Note that the above assumes that your entities are all implemented as NSManagedObjects. If you have created separate subclasses for each entity, then you can simplify some of the above code. For example, valueForKey: and setValue:forKey: can be replaced by the equivalent property accessor methods using dot notation, eg.:
[mySupermarketProductDetails setValue:primaryProductForGivenMarket forKey:@"primaryProductForGivenMarket"];
would become:
mySupermarketProductDetails.primaryProductForGivenMarket = primaryProductForGivenMarket;
and
[mySupermarket valueForKey:@"name"]
can be replaced by:
mySupermarket.name
Likewise, objects should be created with the appropriate subclass rather than NSManagedObject. eg.
NSManagedObject *mySupermarketProductDetails = [NSEntityDescription insertNewObjectForEntityForName:@"SupermarketProductDetails" inManagedObjectContext:context];
would become
SupermarketProductDetails *mySupermarketProductDetails = [NSEntityDescription insertNewObjectForEntityForName:@"SupermarketProductDetails" inManagedObjectContext:context];