Reputation: 1500
I am using RestKit 0.20.1 to map an XML feed to a Core Data Model. These are as follows:
<?xml version="1.0" encoding="utf-8"?>
<payload>
<competitions>
<competition id="100" name="Comp A" />
<competition id="200" name="Comp B" />
<competition id="300" name="Comp C" />
<competition id="400" name="Comp D" />
</competitions>
<seasons>
<season id="10" span="2008/09"/>
<season id="20" span="2009/10"/>
<season id="30" span="2010/11"/>
<season id="40" span="2011/12"/>
<season id="50" span="2012/13"/>
</seasons>
<players>
<player id="1" name="Justyn Spooner">
<season id="10">
<playerstats competitionID="100" goals="0" played="0" />
<playerstats competitionID="200" goals="5" played="4" />
<playerstats competitionID="300" goals="2" played="1" />
</season>
<season id="20">
<playerstats competitionID="300" goals="1" played="4" />
<playerstats competitionID="400" goals="2" played="9" />
</season>
</player>
</players>
</payload>
So far I have the entity mappings setup and the response descriptors configured but am not sure how to setup the relationships between them.
RKEntityMapping *playerMapping = [RKEntityMapping mappingForEntityForName:@"Player" inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]];
playerMapping.identificationAttributes = @[@"attID"];
[playerMapping addAttributeMappingsFromDictionary:@{
@"id" : @"attID",
@"name" : @"attName"
}];
RKEntityMapping *competitionMapping = [RKEntityMapping mappingForEntityForName:@"Competition" inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]];
competitionMapping.identificationAttributes = @[@"attID"];
[competitionMapping addAttributeMappingsFromDictionary:@{
@"id" : @"attID",
@"name" : @"attName"
}];
RKEntityMapping *seasonMapping = [RKEntityMapping mappingForEntityForName:@"Season" inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]];
seasonMapping.identificationAttributes = @[@"attID"];
[seasonMapping addAttributeMappingsFromDictionary:@{
@"id" : @"attID",
@"span" : @"attYearSpan"
}];
RKEntityMapping *playerStatsMapping = [RKEntityMapping mappingForEntityForName:@"PlayerStats" inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]];
playerStatsMapping.identificationAttributes = @[@"attFKCompetitionID", @"attFKSeasonID", @"attFKPlayerID"];
[playerStatsMapping addAttributeMappingsFromDictionary:@{
@"competitionID" : @"attFKCompetitionID",
@"????" : @"attFKSeasonID",
@"????" : @"attFKPlayerID",
@"goals" : @"attGoals",
@"played" : @"attGamesPlayed"
}];
Response Descriptors
RKResponseDescriptor *playerResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:playerMapping pathPattern:kURLBasePath@"/players" keyPath:@"payload.players.player" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
RKResponseDescriptor *seasonResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:seasonMapping pathPattern:kURLBasePath@"/players" keyPath:@"payload.seasons.season" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
RKResponseDescriptor *competitionResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:competitionMapping pathPattern:kURLBasePath@"/players" keyPath:@"payload.competitions.competition" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
RKResponseDescriptor *playerStatsResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:playerStatsMapping pathPattern:kURLBasePath@"/players" keyPath:@"payload.players.player.season.playerstats" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
Aside from the missing relationships, you'll notice that in the playerStatsMapping I need to add an identificationAttribute that is made up of the three primary keys of Player, Season and Competition. The competition id is easily mapped as it is directly under the keyPath payload.players.player.season.playerstats
(defined in the playerStatsResponseDescriptor
). The problem is that I don't know how to reference the parent.id
and parent.parent.id
from the playerStatMapping
to map to the attFKSeasonID and attFKPlayerID respectively.
I don't think RestKit support accessing a parent keyPath in the entityMappings and I'm sure there is probably another way around this? This diagram show what I want to pull out:
In pseudo code, this is what I would be wanting to do if I wasn't using RestKit:
For each player in the XML response:
{
find out if that player exists in Core Data; create if not
keep it around in a local variable
for each season under the player in the XML:
{
create if needed; keep around.
for each competition under the season in the XML:
{
create if needed; keep around.
Take the current player, season and competition.
Is there a PlayerStat matching those three things? Create if not
Set that player stat's attGoals and attGamesPlayed to the values that are mapped from goals and played in the XML
}
}
}
So there are essentially two questions here:
player
and season
ids when constructing the playerStatsMapping
so that the playerStatsMapping
can use them as the identificationAttributes
?Any help would be greatly appreciated.
Thanks, Justyn
Upvotes: 1
Views: 711
Reputation: 1500
In short, RestKit now supports the @parent
and @root
mapping keys as part of the development branch. This allows access to the parent nodes of the currently mapped object IF it is being mapped as a relationship of its parent entity.
This is very similar to another issue I had, I can provide an answer to the specific case above in more detail if required, otherwise please take a look at this answer.
Upvotes: 1