从Web服务检索数据并有效填充SQLite3数据库

时间:2013-12-16 15:48:47

标签: ios objective-c cocoa-touch sqlite

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

该应用程序将从应用程序创建的数据库中提取数据,并通过Web服务填充该数据库。 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数据并将其存储在临时数组“对象”中。我认为我现在需要的是,在每个迭代中,'objects'数组被复制到数据库中的相关表,即'speaker'表名称建立连接:https://testapi.someURL.com/api/congress/speaker并且JSON被输入到数据库中在表'扬声器'下。我该怎么做?我是否需要为startUpdate添加完成处理程序?如果是这样,怎么样?尽管看了几个例子,但我不了解完成处理程序。感谢。

1 个答案:

答案 0 :(得分:0)

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

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

如果您只想更改一点,请开始使用NSOperationQueue来限制您同时尝试制作的连接数。最好也使用核心数据。

如果您愿意做出更大的改变,请务必转向Core Data,然后使用像RestKit这样的框架为您完成所有下载,映射和存储。

(注意,在这两种情况下,您都需要设置最大并发操作限制,以防止应用程序使用请求充斥网络 - 限制为5应该是好的。)