gpt4 book ai didi

objective-c - iOS,使用 RestKit 搜索远程服务器

转载 作者:可可西里 更新时间:2023-11-01 04:42:24 24 4
gpt4 key购买 nike

我正在开发一个应用程序,我想在其中对服务器进行远程搜索。我希望 RestKit 将检索到的数据保存到数据库中。我首先执行本地搜索(目前有效),然后我想进行远程搜索,然后用新结果更新 TableView 。

我有两个问题,1. 我的映射应该是什么样子,以及 2. json 返回一个包含两种不同类型对象的数组。

URL 如下所示:

search.json?search=[search string]

它返回的 JSON 如下所示:

[
{
"event": {
"id": 2,
[...]
},
{
"news": {
"id": 16,
[...]
}

其中 event 和 news 是两种对象。

在我的应用程序中,我有三个模型,Post(抽象实体和父类(super class))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="];

我的搜索代码如下所示(本地搜索有效):

- (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: ''
}

任何关于我应该如何做或可以做的提示都将不胜感激。

最佳答案

我以前没有使用过托管对象,但在这里要做的第一件事是激活 restkit 日志对象映射和网络请求,这样您就可以检查 restkit 从服务器获取了什么以及映射是如何工作的。

//This can be added in your app delegate
RKLogConfigureByName("RestKit/Network", RKLogLevelDebug);
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);

其次,根据您的 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"];

然后像这样加载你的数据:

- (void)loadArticles {
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/articles" delegate:self];
}

另一种方法是按对象映射,因此 RestKit 会检测对象的种类并执行映射,然后您向任何路径发出请求。

如果您有任何问题,请发表评论,我会根据需要改进我的回答。

关于objective-c - iOS,使用 RestKit 搜索远程服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11878847/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com