我正在开发一个应用程序,允许用户浏览/搜索书籍并下载它们。 有3个UITableView,下载/搜索/浏览
如果没有下载,我想显示“下载”按钮,否则,显示“打开”按钮。 它在下载tableview中是直截了当的,我只是查询并显示核心数据中的所有书籍。
服务器是无状态的,不知道用户是否下载了这本书。
我将下载的图书保存在核心数据中。使用FetchedResultsController下载tableview。
当用户按类别搜索/浏览时,启动一个新的REST请求并使用响应的JSON作为内存NSArray来备份tableview以显示标题和作者姓名等。
书籍清单很大,服务器支持一些高级搜索,例如使用Acronym并按人气排序。因此,下载整个列表并在本地执行搜索需要更多工作。
更新的好方法是确定是否在搜索视图中下载了图书?每次在主线程cellForRowAtIndexPath
中查询核心数据库听起来都很昂贵。
我还希望在后台下载完成后实时更新UI状态,因此在下载后也无法修改JSON
由于
答案 0 :(得分:1)
如果书籍清单很小(足够小,你可以一次性从服务器上下载),你可能会在内存中为它建立模型。尝试查询服务器,修改CoreData结果的响应(全部在后台),然后告诉UITableView
重新加载自己(在UI线程中)。
伪代码说明:
dispatch_async(..., ^{
[server requestData:param onComplete:^(NSDictionary* result){
NSArray* someResult = [moc executeFetchRequest:...];
NSArray* tableViewData = [mybusinesslogic mergeServerResult:result
withCoreDataResult:someResult];
myTableViewController.tableViewData = tableViewData;
dispatch_async(dispatch_get_main_queue(), ^{
[myTableViewController.tableView reloadData];
});
}];
});
答案 1 :(得分:0)
为每个单元格执行核心数据查询非常昂贵。所以做一个查询,然后在内存中匹配它。如果书籍有一些容易匹配的id。也许是这样的:
1)获取响应的JSON NSArray。 (也许可以将ID解析为另一个NSArray) 2)在单个查询中将ID匹配到核心数据中的ID。返回只包含匹配ID的数组,如下所示:
-(NSArray*) findMatchInGraph:(NSManagedObjectContext*)context forResults:(NSArray*)searchResultIDs {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity: [NSEntityDescription entityForName:@"Books" inManagedObjectContext:context]];
NSPredicate *reqPredicate = [NSPredicate predicateWithFormat:@"(id IN %@)", searchResults;
[request setPredicate:reqPredicate];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
NSMutableArray *matching = [NSMutableArray array];
if (results) {
for (NSManagedObject *item in results) {
[matching addObject:[item valueForKey:@"id"]];
}
}
return [matching copy];
}
3)TableViewController,具有匹配ID的索引的单元格将添加“已下载”指示符?
这可能是一种更有效的方式。