2014-12-08 82 views
0

我的代码调用HTTP后调用远程服务器,并获得JSON格式的结果,我已经提取了这个JSON,但现在我需要将这些结果存储到SQLite。根据我的阅读NSURLSessionDataTask是后台线程,所以我的困惑是,我应该打开SQL调用并插入completionHandler(或)是否有任何其他最佳做法来处理这种类型的需求?将NSURLSessionDataTask响应存储到SQLite数据库?

编辑1

我奋力更多的一点是,它是有效的写“completionHandler”里面的SQLite操作? “completionHandler”会被视为单独线程(正在执行SessionDataTask)还是主线程的方法?

EDIT 2

我打开CoreData相关的解决方案了。

任何帮助,将不胜感激。

NSURL *loginUrl = [NSURL URLWithString:@"myurl"]; 
NSURLSession *session = [NSURLSession sharedSession]; 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:loginUrl]; 
request.HTTPMethod = @"POST"; 
NSString *ipData = [NSString stringWithFormat:@"uName=%@&pwd=%@",self.userName.text,self.userPwd.text]; 
request.HTTPBody = [ipData dataUsingEncoding:NSUTF8StringEncoding]; 


NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *jsonError) { 
    NSLog(@"Inside post data task......"); 

    NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response; 
    if(httpResp.statusCode == 200) 
    { 
     NSLog(@"Response succesfull........."); 
     NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError]; 

     if(!jsonError) 
     { 
      //No Json error 
      NSString *uName = jsonDict[@"userName"]; 
      NSString *uID = jsonDict[@"uID"]; 
      //HOW CAN I INSERT THESE DETAILS TO SQLITE DB BEFORE CALLING SEGUE TO MOVE TO NEXT SCREEN? 
      dispatch_async(dispatch_get_main_queue(), ^{ 
        [self performSegueWithIdentifier:@"mysegueID" sender:self]; 
       }); 
      } 
    }else 
    { 
     NSLog(@"Response is not succesfulll..."); 
    } 
}]; 

[postDataTask resume]; 
+0

只是为了澄清,直接SQL而不是CoreData是你想要的,对吧? (另外,为什么?) – RobP 2014-12-11 16:41:43

+0

感谢您的问题! 1)我是iOS开发新手(来自Android背景),所以SQLite的SQL查询对我来说更容易。 2)我的应用程序不是SQLite密集型的,换句话说,只有一次插入数据,剩余时间只读。希望它是有道理的。 – kosa 2014-12-11 16:51:05

+0

当然,即使对于简单的SQL使用情况,CoreData也有一些优势。我发现这个链接有助于解释原因。迁移到未来的架构版本就是它为您处理好的一个例子。 http://sealedabstract.com/code/you-should-use-core-data/ – RobP 2014-12-11 17:06:19

回答

1

很多人使用FMDB作为sqlite的objective-c包装。

在NSURLSession的情况下,完成处理程序的块将在“委托队列”上执行(请参阅NSURLSession的delegateQueue属性)。

只要您遵循SQLite线程规则,在完成处理程序中执行SQLite是有效的。我再次向她推荐FMDB,因为它有这方面的帮手。见Using FMDatabaseQueue and Thread Safety

所以,你的例子看起来像:

FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath]; 

NSURL *loginUrl = [NSURL URLWithString:@"myurl"]; 
NSURLSession *session = [NSURLSession sharedSession]; 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:loginUrl]; 
request.HTTPMethod = @"POST"; 
NSString *ipData = [NSString stringWithFormat:@"uName=%@&pwd=%@",self.userName.text,self.userPwd.text]; 
request.HTTPBody = [ipData dataUsingEncoding:NSUTF8StringEncoding]; 


NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *jsonError) { 
    NSLog(@"Inside post data task......"); 

    NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response; 
    if(httpResp.statusCode == 200) 
    { 
     NSLog(@"Response succesfull........."); 
     NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError]; 

     if(!jsonError) 
     { 
      //No Json error 
      NSString *uName = jsonDict[@"userName"]; 
      NSString *uID = jsonDict[@"uID"]; 
      //HOW CAN I INSERT THESE DETAILS TO SQLITE DB BEFORE CALLING SEGUE TO MOVE TO NEXT SCREEN? 
      [queue inDatabase:^(FMDatabase *db) { 
        NSDictionary *argsDict = @{ @"uName" : uName, @"uID" : uID}; 
        [db executeUpdate:@"INSERT INTO myTable (name) VALUES (:name)" withParameterDictionary:argsDict]; 
      }]; 

      dispatch_async(dispatch_get_main_queue(), ^{ 
        [self performSegueWithIdentifier:@"mysegueID" sender:self]; 
       }); 
      } 
    } 
    else 
    { 
     NSLog(@"Response is not succesfulll..."); 
    } 
}]; 

[postDataTask resume]; 
+0

感谢您的回答!我挣扎得更多的是,在“completionHandler”中写入SQLite操作(使用原始SQL(或)任何框架)是否有效? “completionHandler”会被视为单独的线程(正在执行SessionDataTask)还是主线程?你能帮助解答这些问题吗? – kosa 2014-12-11 17:20:05

+0

我更新了我的答案,希望有所帮助。 – catlan 2014-12-11 19:29:16

+0

好的。得到它了。谢谢! – kosa 2014-12-12 05:05:55

1

一个SQLite数据库可以从一个应用程序的任何线程访问。唯一的限制是SQLite不会高兴地容忍来自多个线程的同时访问(在这里“同时”适用于“事务”的持续时间,而不仅仅是调用SQLite方法的持续时间)。

所以你必须以某种方式确保永远不会同时访问。一个简单的方法是始终使用相同的线程(例如主线程)进行访问。或者您可以实施“软”协议,以便您知道两个操作不会同时尝试使用数据库,因为它们在时间上是分开的。或者您可以在软件/操作系统中使用Objective-C锁定或其他同步机制。

+0

明白了。谢谢! – kosa 2014-12-12 05:04:55

相关问题