【发布时间】:2013-12-15 21:42:58
【问题描述】:
我这几天一直在与 RestKit 进行关系映射。我可以很好地得到一个对象,但是嵌套的 JSON 数据数组没有被映射并且查看跟踪日志我找不到任何错误。尽管很痛,但我承认它已经使我受益匪浅。我已经查看了尽可能多的示例,并根据其他人在他们的情况下所做的尝试了不同的解决方案,但没有任何效果。我尝试按照 RestKit 文档随附的 RKGist 示例进行操作,但不幸的是,尚未编写关系映射部分,那里只有占位符。
这是我正在使用的 JSON 示例响应:
{
"stat": {
"code": 200
},
"data": {
"channel": {
"_id": "68413dzz39f4843t8500000d",
"desc": "...",
"name": "...",
"owner": {
"_id": "584ege8239f4883f6200000b",
"name": "..."
},
"count": {
"invited": 0,
"joined": 1,
"subscribers": 0,
"posts": 0,
"messages": 0
},
"access": "PUB"
},
"affiliation": "...",
"member_statuses": [
{
"channel": {
"_id": "68413dzz39f4843t8500000d",
"name": "..."
},
"owner": {
"_id": "584ege8239f4883f6200000b",
"dname": "...",
"name": "..."
},
"type": "...",
"message": "This is the message text",
"_id": "52222e3039f4884tkk00000e",
"taken": "2013-11-11T20:23:45.938Z",
"access": "PUB"
}
]
}
}
我还无法发布图片,因为这是我无法找到答案的第一个问题。但是两个相关的 Core Data 模型和 NSManagedObject 子类是:
THChannel.h
我已经建立了一个名为posts 的关系,其目的地为THPost,其倒数为post。我选择类型为To Many,因为多个帖子可以属于一个频道
@class THPost, THUser;
@interface THChannel : NSManagedObject
@property (nonatomic, retain) NSString * accessCode;
@property (nonatomic, retain) NSString * channelId;
@property (nonatomic, retain) NSNumber * countComments;
@property (nonatomic, retain) NSNumber * countInvited;
@property (nonatomic, retain) NSNumber * countJoined;
@property (nonatomic, retain) NSNumber * countMessages;
@property (nonatomic, retain) NSNumber * countPhotos;
@property (nonatomic, retain) NSNumber * countPosts;
@property (nonatomic, retain) NSNumber * countSubscribers;
@property (nonatomic, retain) NSDate * createdAt;
@property (nonatomic, retain) NSString * desc;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) THUser *owner;
@property (nonatomic, retain) NSSet *posts;
@end
@interface THChannel (CoreDataGeneratedAccessors)
- (void)addPostsObject:(THPost *)value;
- (void)removePostsObject:(THPost *)value;
- (void)addPosts:(NSSet *)values;
- (void)removePosts:(NSSet *)values;
@end
THPost.h
我已经建立了一个名为post 的关系,其目的地为THChannel,其倒数为posts。我选择类型为To One,因为多个帖子可以属于一个频道
@class THChannel, THUser;
@interface THPost : NSManagedObject
@property (nonatomic, retain) NSString * postId;
@property (nonatomic, retain) NSString * channelId;
@property (nonatomic, retain) NSString * ownerTypeCode;
@property (nonatomic, retain) NSString * ownerId;
@property (nonatomic, retain) NSString * postTypeCode;
@property (nonatomic, retain) NSString * messageText;
@property (nonatomic, retain) NSDate * createdAt;
@property (nonatomic, retain) NSDate * takenAt;
@property (nonatomic, retain) NSString * accessTypeCode;
@property (nonatomic, retain) THChannel *post;
@property (nonatomic, retain) THUser *owner;
@end
AppDelegate.m
// Log all HTTP traffic with request and response bodies
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
// Log debugging info about Core Data
RKLogConfigureByName("RestKit/CoreData", RKLogLevelDebug);
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);
NSError *error = nil;
NSURL *baseURL = [NSURL URLWithString:API_BASE_URL];
NSIndexSet *successStatusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx status codes
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:baseURL];
// Initialize managed object store
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
[managedObjectStore createPersistentStoreCoordinator];
NSString *path = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"MyApp.sqlite"];
NSDictionary *options = @{ NSMigratePersistentStoresAutomaticallyOption: @(NO),
NSInferMappingModelAutomaticallyOption: @(NO) };
NSPersistentStore *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:path fromSeedDatabaseAtPath:nil withConfiguration:nil options:options error:&error];
if (! persistentStore) {
RKLogError(@"Failed adding persistent store at path '%@': %@", path, error);
}
[managedObjectStore createManagedObjectContexts];
RKEntityMapping *channelEntityMapping = [RKEntityMapping mappingForEntityForName:@"THChannel" inManagedObjectStore:managedObjectStore];
channelEntityMapping.identificationAttributes = @[ @"channelId" ];
[channelEntityMapping addAttributeMappingsFromDictionary:@{ @"_id": @"channelId",
@"name": @"name",
@"desc": @"desc",
@"access": @"accessCode",
@"nmupl": @"nonMemberUploads",
@"meta.created": @"createdAt",
@"affiliation": @"viewerAffiliationCode",
@"canPost": @"viewerCanPost",
@"count.subscribers": @"countSubscribers",
@"count.comments": @"countComments",
@"count.posts": @"countPosts",
@"count.photos": @"countPhotos",
@"count.messages": @"countMessages",
@"count.joined": @"countJoined",
@"count.invited": @"countInvited" }];
RKEntityMapping *postEntityMapping = [RKEntityMapping mappingForEntityForName:@"THPost" inManagedObjectStore:managedObjectStore];
postEntityMapping.identificationAttributes = @[ @"postId" ];
[postEntityMapping addAttributeMappingsFromDictionary:@{ @"_id": @"postId",
@"channel._id": @"channelId",
@"type": @"postTypeCode",
@"message": @"messageText",
@"meta.created": @"createdAt",
@"taken": @"takenAt",
@"access": @"accessTypeCode"
}];
[channelEntityMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"member_statuses" toKeyPath:@"posts" withMapping:postEntityMapping]];
NSEntityDescription *postEntity = [NSEntityDescription entityForName:@"THPost" inManagedObjectContext:managedObjectStore.mainQueueManagedObjectContext];
NSRelationshipDescription *postRelationship = [postEntity relationshipsByName][@"post"];
RKConnectionDescription *connection2 = [[RKConnectionDescription alloc] initWithRelationship:postRelationship attributes:@{ @"channelId": @"channelId" }];
[postEntityMapping addConnection:connection2];
RKResponseDescriptor *channelsOverviewObjectDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:channelEntityMapping
method:RKRequestMethodAny
pathPattern:@"/channels/:channelID"
keyPath:@"data.channel"
statusCodes:successStatusCodes];
[manager addResponseDescriptorsFromArray:@[channelsOverviewObjectDescriptor]];
// Set the default store shared instance
manager.managedObjectStore = managedObjectStore;
[RKObjectManager setSharedManager:manager];
【问题讨论】:
标签: ios rest restkit restkit-0.20