从Web服务检索数据并高效地填充SQLite3数据库 [英] Retrieving data from web service and populating SQLite3 database efficiently

查看:64
本文介绍了从Web服务检索数据并高效地填充SQLite3数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am currently developing an app that that will be used by association members that are going to a large annual conference.

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

The app will pull data from a database that is created by the app and populate it via a web service. The web service is split into 8 pages (this will likely go up). Each page represents a table in the database. The app will have several table views that will be populated by data in one or more of the tables in the database.

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

What I need is a the best method for going through the list of tables, connecting to their respective web service pages and then populating the respective database tables. This updating needs to take place in the background so the UI doesn't become unresponsive and/or show a downloading/updating/waiting kind of status.

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

So far I have a static array of the table names and have a loop that goes through the array and appends a URL string with the names, for example:

-(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方法具有连接并检索数据:

fetchObjectsWithTableName method then has the connections and retrieves the data:

-(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输入到数据库 speaker下的数据库中。我如何以及在哪里做?我需要添加完成处理程序到startUpdate吗?如果是这样,怎么办?尽管看了几个例子,我还是不了解完成处理程序。谢谢。

This currently goes through the array of table names, makes a connection based on each one and pulls back JSON data and stores it in a temporary array 'objects'. I think what I need now is that in each iteration of this 'objects' array is copied to the relevant table in the database, i.e. 'speaker' table name makes a connection: https://testapi.someURL.com/api/congress/speaker and the JSON is entered into the database under the table 'speaker'. How and where do I do that? Will I need to add a completion handler to startUpdate? If so, how? I don't understand completion handlers despite looking at several examples. Thanks.

推荐答案

否,请在完成后的 NSURLConnection 块中进行操作您已经更新了临时存储。

No, do it in the NSURLConnection completion block after you have updated your temporary storage.

但是,总体上改变您的方法。

But, change your approach overall.

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

If you're only willing to change a bit, start using NSOperationQueue to limit the number of connections that you're trying to make at the same time. Preferably also use Core Data.

如果您愿意进行更大的更改,请绝对使用Core Data并考虑使用RestKit之类的框架来完成所有为您下载,映射和存储。

If you're willing to make a bigger change, definitely move to Core Data and look at using a framework like RestKit to do all of the download, mapping and storage for you.

(请注意,在两种情况下,您都需要设置最大并发操作限制,以防止应用程序向请求泛洪-a限制为5应该很好。)

(note, in both cases you need to set the max concurrent operation limit to prevent the app from flooding the network with requests - a limit of 5 should be good).

这篇关于从Web服务检索数据并高效地填充SQLite3数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆