I have an NSManagedObject
subclass TAGRemoteObject
TAGRemoteObject.h
extern const struct TAGRemoteObjectAttributes {
__unsafe_unretained NSString *object_Id;
} TAGRemoteObjectAttributes;
@interface TAGRemoteObject ()
@property (nonatomic, strong) NSString *object_Id;
@end
TAGRemoteObject.m
const struct TAGRemoteObjectAttributes TAGRemoteObjectAttributes = {
.object_Id = @"object_Id",
};
@implementation TAGRemoteObject
@dynamic object_Id;
+(RKEntityMapping*)entityMappingInManagedObjectStore:(RKManagedObjectStore *)managedObjectStore
{
RKEntityMapping *entityMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([self class]) inManagedObjectStore:managedObjectStore];
[entityMapping addAttributeMappingsFromDictionary:@{
@"object_id" : TAGRemoteObjectAttributes.object_Id,
}];
[entityMapping setIdentificationAttributes:@[ TAGRemoteObjectAttributes.object_Id ]];
return entityMapping;
}
@end
Then I have two subclasses of TAGRemoteObject
. TAGPost
has a one-to-many viewedUsers
relationship to TAGUser
. TAGUser
also has a one-to-many posts
relationship to TAGPost
.
TAGPost.h
extern const struct TAGPostRelationships {
__unsafe_unretained NSString *viewedUsers;
} TAGPostRelationships;
@interface TAGPost : TAGRemoteObject ()
@property (nonatomic, strong) NSSet *viewedUsers;
@end
TAGPost.m
const struct TAGPostRelationships TAGPostRelationships = {
.viewedUsers = @"viewedUsers",
};
@implementation TAGPost
@dynamic viewedUsers;
+(RKEntityMapping*)entityMappingInManagedObjectStore:(RKManagedObjectStore *)managedObjectStore
{
RKEntityMapping *entityMapping = [super entityMappingInManagedObjectStore:managedObjectStore];
RKEntityMapping *userMapping = [TAGUser entityMappingInManagedObjectStore:managedObjectStore];
RKRelationshipMapping *viewedUsersMapping = [RKRelationshipMapping relationshipMappingFromKeyPath:@"viewed_users" toKeyPath:TAGJourneyOutgoingPostRelationships.viewedUsers withMapping:userMapping];
viewedUsersMapping.assignmentPolicy = RKUnionAssignmentPolicy;
[entityMapping addPropertyMapping:viewedUsersMapping];
return entityMapping;
}
@end
TAGUser.h
extern const struct TAGUserAttributes {
__unsafe_unretained NSString *username;
} TAGUserAttributes;
extern const struct TAGUserRelationships {
__unsafe_unretained NSString *posts;
}
@interface TAGUser : TAGRemoteObject ()
@property (nonatomic, strong) NSString *username;
@property (nonatomic, strong) NSSet *posts;
@end
TAGUser.m
const struct TAGUserAttributes TAGUserAttributes = {
.username = @"username",
};
const struct TAGUserRelationships TAGUserRelationships = {
.posts = @"posts",
};
@implementation TAGUser
@dynamic username;
@dynamic posts;
+(RKEntityMapping*)entityMappingInManagedObjectStore:(RKManagedObjectStore *)managedObjectStore
{
RKEntityMapping *entityMapping = [super entityMappingInManagedObjectStore:managedObjectStore];
[entityMapping addAttributeMappingsFromDictionary:@{
@"username" : TAGUserAttributes.username,
}];
RKEntityMapping *postEntityMapping = [TAGPost entityMappingInManagedObjectStore:managedObjectStore];
RKRelationshipMapping *postsRelationshipMapping = [RKRelationshipMapping relationshipMappingFromKeyPath:@"posts" toKeyPath:TAGUserRelationships.posts withMapping:postEntityMapping];
postsRelationshipMapping.assignmentPolicy = RKUnionAssignmentPolicy;
[entityMapping addPropertyMapping:postsRelationshipMapping];
return entityMapping;
}
@end
The issue I'm having is that when I receive a JSON response like this for the home feed which has many users, I get a viewedUsers.count
of 3 which is expected:
{
"error": null,
"result": [
{
"object_id": 1,
"username": "a",
"posts": [
{
"object_id": 299,
"viewed_users": [
{
"object_id": 3,
"username": "b"
},
{
"object_id": 4,
"username": "b"
},
{
"object_id": 5,
"username": "b"
}
]
}
]
}
]
}
But when I send a request for all the posts for user 1
and get the following response, viewedUsers.count
is either 0 or 1 randomly for every post:
{
"error": null,
"result": [
{
"object_id": 299,
"viewed_users": [
{
"object_id": 3,
"username": "b"
},
{
"object_id": 4,
"username": "b"
},
{
"object_id": 5,
"username": "b"
}
]
},
{
"object_id": 300,
"viewed_users": [
{
"object_id": 3,
"username": "b"
},
{
"object_id": 4,
"username": "b"
}
]
},
{
"object_id": 301,
"viewed_users": [
{
"object_id": 3,
"username": "b"
},
{
"object_id": 4,
"username": "b"
},
{
"object_id": 5,
"username": "b"
}
]
}
]
}
When I send the request to homefeed, I map to [TAGUser entityMappingInManagedObjectStore:self.objectManager.managedObjectStore];
When I send a request to get the posts for the user, I map to [TAGPost entityMappingInManagedObjectStore:self.objectManager.managedObjectStore];
I'm really lost as to why the mapping just doesn't work sometimes. When I set RestKit's logging level to RKLogLevelTrace
, it sees the JSON array of length 3, but after mapping, the relationship only has 0 or 1.
Edit: I suspected that the circular relationship might be the issue, so I removed the posts
relationship from the TAGUser
mapping. I'm still seeing the issue though.
Turns out the relationship was set to one-to-many, when it should have been set to many-to-many.