【问题标题】:Retrieving data from web service and populating SQLite3 database efficiently从 Web 服务中检索数据并有效地填充 SQLite3 数据库
【发布时间】:2013-12-16 15:48:46
【问题描述】:

我目前正在开发一款应用程序,供参加大型年度会议的协会成员使用。

应用程序将从应用程序创建的数据库中提取数据并通过网络服务填充它。 Web 服务分为 8 页(这可能会增加)。每个页面代表数据库中的一个表。该应用程序将具有多个表视图,这些视图将由数据库中一个或多个表中的数据填充。

我需要的是浏览表列表、连接到它们各自的 Web 服务页面然后填充各自的数据库表的最佳方法。此更新需要在后台进行,这样 UI 才不会变得无响应和/或显示下载/更新/等待状态。

到目前为止,我有一个表名的静态数组,并有一个循环遍历该数组并附加一个带有名称的 URL 字符串,例如:

-(void)startUpdate
{
NSArray* tableNames =  @[@"speaker", @"exhibitor", @"workshop", @"workshopspeakers", @"schedule", @"location", @"feedback", @"note", @"usage", @"user"];

NSUInteger loopCount = tableNames.count;

for (int i = 0; i < loopCount; ++i){
    NSString *tableName = [tableNames objectAtIndex:i];   
    [self fetchObjectsWithTableName:[tableName mutableCopy] completion:^(NSArray* objects, NSError*error){
        if (error) {
        } else {
        }
    }];
}
}

fetchObjectsWithTableName 方法然后具有连接并检索数据:

-(void)fetchData:(NSString *)tableName
                    withCompletion:(completion_t)completionHandler
{
NSString *currentURL = [NSString stringWithFormat:@"https://testapi.someURL.com/api/congress/%@", tableName];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:currentURL]];
[request addValue:@"application/json" forHTTPHeaderField:(@"Accept")];
[NSURLConnection sendAsynchronousRequest:request
                                   queue:[[NSOperationQueue alloc] init]
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
 {
     NSError* err = error;
     NSArray* objects; // final result array as a representation of JSON Array
     if (response) {
         NSHTTPURLResponse *newResp = (NSHTTPURLResponse*)response;
         if (newResp.statusCode == 200) {
             NSLog(@"FetchData - Status code = %li", (long)newResp.statusCode);
             if ([data length] >0 && error == nil)
             {
                 NSError* localError;
                 objects = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
                 if (objects) {
                     if (completionHandler) {
                         completionHandler(objects, nil);
                     }
                     //NSLog(@"Objects in current table - %@ = %@", tableName, objects);
                     [self.tables addObject:objects];
                   //  NSLog(@"Tables now = %@", self.tables);
                     NSLog(@"FetchData - Objects in current table - %@ = %lu", tableName, (unsigned long)objects.count);
                     return;
                 } else {
                     err = localError;
                 }
             } else {
                 NSLog(@"FetchData - objects is empty");
                 return;
                // err = ...
             }
         }
         NSLog(@"FetchData - Response code not 200@");
     }
     if (objects == nil) {
         NSLog(@"FetchData - Nothing found in table: %@", tableName);
         //assert(err);
         if (completionHandler) {
             completionHandler(nil, err);
         }
     }
}];

}

目前这会遍历表名数组,根据每个表名建立连接,然后拉回 JSON 数据并将其存储在临时数组“对象”中。我想我现在需要的是,在这个“对象”数组的每次迭代中,都被复制到数据库中的相关表中,即“扬声器”表名建立连接:https://testapi.someURL.com/api/congress/speaker 并且 JSON 被输入到数据库中表“扬声器”。我如何以及在哪里这样做?我需要向 startUpdate 添加完成处理程序吗?如果是这样,怎么做?尽管查看了几个示例,但我不了解完成处理程序。谢谢。

【问题讨论】:

    标签: ios objective-c cocoa-touch sqlite


    【解决方案1】:

    不,请在更新临时存储后在 NSURLConnection 完成块中执行此操作。

    但是,整体改变你的方法。

    如果您只愿意稍作更改,请开始使用NSOperationQueue 来限制您尝试同时建立的连接数。最好也使用 Core Data。

    如果你愿意做出更大的改变,一定要迁移到 Core Data 并考虑使用像 RestKit 这样的框架来为你完成所有的下载、映射和存储。

    (请注意,在这两种情况下,您都需要设置最大并发操作限制,以防止应用程序向网络发出大量请求 - 限制为 5 应该不错)。

    【讨论】:

    • 感谢您的建议,限制连接是有道理的,因为我希望应用程序高效,并且在快速响应的同时不要使用过多的任何资源。在这种情况下使用 Core Data over SQLite3 有什么好处?我喜欢在首次启动时构建和预填充数据库的想法,然后在需要时允许对其进行更新。
    • Core Data(可以)在幕后使用 SQLite,它只是提供了一个很好的简单(高级)界面。 RestKit 将 Core Data 包装起来,允许您发出高级请求并指定传入数据如何映射到 Core Data。然后使用获取的结果控制器来观察数据,这样您就不会直接从数据存储中进行任何获取。
    • CoreData 在处理通过各种视图和用户界面同步数据方面非常方便。另一方面,它不是数据库,尽管它使用了一个。直接数据库可能最适合您的应用程序,但您应该根据数据做出选择。
    猜你喜欢
    • 2013-10-17
    • 2023-03-08
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多