And*_*ers 5 search core-data objective-c ios restkit
我正在开发一个应用程序,我想对服务器进行远程搜索.我希望RestKit将检索到的数据保存到数据库中.我首先执行本地搜索(当前有效),然后我想进行远程搜索,然后使用新结果更新表格视图.
我有两个问题,1.我的映射应该如何; 2. json返回一个包含两种不同对象的数组.
URL如下所示:
search.json?search=[search string]
Run Code Online (Sandbox Code Playgroud)
它返回的JSON如下所示:
[
{
"event": {
"id": 2,
[...]
},
{
"news": {
"id": 16,
[...]
}
Run Code Online (Sandbox Code Playgroud)
事件和新闻是两种对象.
在我的应用程序中,我有三个模型,Post(抽象实体和超类)NewsPost(子类到Post)和Event(子类到Post).
我的映射看起来像这样:
RKManagedObjectMapping* newsMapping = [RKManagedObjectMapping mappingForClass:[NewsPost class] inManagedObjectStore:objectManager.objectStore];
newsMapping.primaryKeyAttribute = @"newsId";
newsMapping.rootKeyPath = @"news";
[newsMapping mapKeyPath:@"id" toAttribute:@"newsId"];
RKManagedObjectMapping *eventMapping = [RKManagedObjectMapping mappingForClass:[CalendarEvent class] inManagedObjectStore:objectManager.objectStore];
eventMapping.primaryKeyAttribute = @"calendarId";
eventMapping.rootKeyPath = @"calendars";
[eventMapping mapKeyPath:@"id" toAttribute:@"calendarId"];
// These two works.
[objectManager.mappingProvider setObjectMapping:newsMapping forResourcePathPattern:@"/package_components/1/news"];
[objectManager.mappingProvider setObjectMapping:eventMapping forResourcePathPattern:@"/package_components/1/calendars"];
// I don't know how these should look/work.
// Since the search word can change
[objectManager.mappingProvider setObjectMapping:eventMapping forResourcePathPattern:@"/package_components/1/search\\.json?search="];
[objectManager.mappingProvider setObjectMapping:newsMapping forResourcePathPattern:@"/package_components/1/search\\.json?search="];
Run Code Online (Sandbox Code Playgroud)
我的搜索代码如下(本地搜索工作):
- (void)setUpSearch
{
if (self.searchField.text != nil) {
[self.posts removeAllObjects];
[self.events removeAllObjects];
[self.news removeAllObjects];
// Search predicates.
// Performs local search.
NSPredicate *contactNamePredicate = [NSPredicate predicateWithFormat:@"contactName contains[cd] %@", self.searchField.text];
NSPredicate *contactDepartmentPredicate = [NSPredicate predicateWithFormat:@"contactDepartment contains[cd] %@", self.searchField.text];
[...]
NSArray *predicatesArray = [NSArray arrayWithObjects:contactNamePredicate, contactDepartmentPredicate, contactEmailPredicate, contactPhonePredicate, linkPredicate, titlePredicate, nil];
NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicatesArray];
self.posts = [[Post findAllWithPredicate:predicate] mutableCopy];
if (self.posts.count != 0) {
self.noResultsLabel.hidden = YES;
for (int i = 0; i < self.posts.count; i++) {
Post * post = [self.posts objectAtIndex:i];
if (post.calendarEvent == YES) {
[self.events addObject:post];
} else {
[self.news addObject:post];
}
}
}
// reload the table view
[self.tableView reloadData];
[self performRemoteSearch];
}
}
- (void)search
{
[self setUpSearch];
[self hideKeyboard];
[self performRemoteSearch];
}
- (void)performRemoteSearch
{
// Should load the objects from JSON
// Note that the searchPath can vary depending on search text.
NSString *searchPath = [NSString stringWithFormat:@"/package_components/1/search.json?search=%@", self.searchField.text];
RKObjectManager *objectManager = [RKObjectManager sharedManager];
[objectManager loadObjectsAtResourcePath:searchPath delegate:self];
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects
{
// This never gets called.
// Should update my arrays and then update the tableview, but it never gets called.
// Instead I get Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 "Could not find an object mapping for keyPath: ''
}
Run Code Online (Sandbox Code Playgroud)
关于我应该或可以做什么的任何提示将不胜感激.
我以前没有使用过托管对象,但这里要做的第一件事是激活对象映射和网络请求上的 Restkit 日志,以便您可以检查 RestKit 从服务器获取的内容以及映射如何工作。
//This can be added in your app delegate
RKLogConfigureByName("RestKit/Network", RKLogLevelDebug);
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);
Run Code Online (Sandbox Code Playgroud)
其次,根据您的 JSON 和您的搜索路径的变化,我认为最好使用关键路径映射而不是资源路径模式。因此,您应该尝试按键映射,如下例所示:
RKObjectMapping* articleMapping = [RKObjectMapping mappingForClass:[Article class]];
[articleMapping mapKeyPath:@"title" toAttribute:@"title"];
[articleMapping mapKeyPath:@"body" toAttribute:@"body"];
[articleMapping mapKeyPath:@"author" toAttribute:@"author"];
[articleMapping mapKeyPath:@"publication_date" toAttribute:@"publicationDate"];
[[RKObjectManager sharedManager].mappingProvider setMapping:articleMapping forKeyPath:@"articles"];
Run Code Online (Sandbox Code Playgroud)
然后加载您的数据,如下所示:
- (void)loadArticles {
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/articles" delegate:self];
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是按对象映射,因此 RestKit 会检测对象的类型并执行映射,然后您可以向任何路径发出请求。
如果您有任何问题,请发表评论,我可以根据需要改进我的答案。
| 归档时间: |
|
| 查看次数: |
1044 次 |
| 最近记录: |