2014-12-08 50 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

相關問題