如何在iOS中在后台运行NSURLConnection

我正在与待办事项列表组织者的应用程序,用户添加注释。 我正在使用coredata数据库来存储笔记。 由于我提供同步function,我正在parsingJSON数据到服务器,并从服务器获取JSON数据。
我正在使用NSURLConnection API及其委托function

- (void)pushData { loop through the notes array and send notes 1 by one [[request setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:jsonData]; m_dataPush = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; [m_dataPush start]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { Process response from server, save to core DB and again pushData if any modified and again process the response } 

我在appEnterBackground和appBecomeActive上调用这个API,因为我想要在多个设备上更新数据。

我面临的问题是这样的

1)当笔记更多时,应用程序正在卡住,当我们退出并打开应用程序,并开始添加笔记。

2)我尝试使用GCD,但是我的NSURLConnection没有给我任何回应

关心Ranjit

Ranjit:根据你对不同反应的意见,我怀疑你是从主线程发送第一个请求。 当您收到第一个响应时,您在后台处理它,然后从后台发送第二个请求。 后续的请求应该从主线程发送

 [self performSelectorOnMainThread:@selector(myMethodToOpenConnection:) withObject:myObject waitUntilDone:NO]; 

否则该线程在调用委托之前退出

你可以像NSURLConnection那样使用NSOperation Queue

 //allocate a new operation queue NSOperationQueue *queue = [[NSOperationQueue alloc] init]; //Loads the data for a URL request and executes a handler block on an //operation queue when the request completes or fails. [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { if ([data length] >0 && error == nil){ //process the JSON response //use the main queue so that we can interact with the screen NSString *myData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"JSON data = %@", myData); NSDictionary *myDict = [myData JSONValue]; } }]; 

它会在后台完成所有的处理。

NSURLConnection提供了一个简便的方法,叫做sendAsynchronousRequest: completionHandler:它可以帮助你工作。 你可以告诉它在主线程上运行完成处理程序。

使用它,你的代码会变得更简单,如下所示:

 // place a declaration in your .h to make it public - (void)pushDataWithCompletion:(void (^)(BOOL, NSError*))completion; - (void)pushDataWithCompletion:(void (^)(BOOL, NSError*))completion { // setup your connection request... [[request setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:jsonData]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { // whatever you do on the connectionDidFinishLoading // delegate can be moved here if (!error) { // did finish logic here, then tell the caller you are done with success completion(YES, nil); } else { // otherwise, you are done with an error completion(NO, error); } }]; } 

确切地说,在这个模块中返回的内容取决于呼叫者关心的内容。 在数据的某个方面收集一个块参数是很常见的。

编辑 – 我忘了上面的NSError后面的指针表示法(*)。

另外,假设你有一个需要服务器处理的对象数组。 这个方法适用于一个通话。 要处理几个,让我们给它一个参数。 说每个音符都是一个NSString *;

 - (void)pushNote:(NSString *)note withCompletion:(void (^)(BOOL, NSError*))completion { // Code is the same except it forms the request body using the note parameter. } 

如果真正的任务是做几个笔记的工作,你需要一个方法,重复调用这个,然后告诉它的调用者它的完成。

 - (void)pushNotes:(NSArray *)notes withCompletion:(void (^)(BOOL, NSError*))completion { // if there are no more notes, we are done if (!notes.count) return completion(YES, nil); NSString *nextNote = notes[0]; NSArray *remainingNotes = [notes subarrayWithRange:NSMakeRange(1, notes.count-1)]; [self pushNote:nextNote withCompletion:^(BOOL success, NSError*error) { // if success, do the rest, or else stop and tell the caller if (success) { [self pushNotes:remainingNotes withCompletion:completion]; } else { completion(NO, error); } }]; }