在NSURLConnection加载数据的同时执行一些任务objective-c

在NSURLConnection加载数据的同时执行一些任务objective-c

问题描述:

我是iOS编程的开始者。我有NSURLConnection的一些问题:我已经安装了SWRevealViewController https://github.com/John-Lluch/SWRevealViewController,当我的应用程序从服务器加载数据时,我无法使用与屏幕的交互。加载数据时无法打开SWR菜单。在NSURLConnection加载数据的同时执行一些任务objective-c

这是我在viewDidLoad中SWR:

SWRevealViewController *revealViewController = self.revealViewController; 
if (revealViewController) { 
    [self.openMenyItmet setTarget: self.revealViewController]; 
    [self.openMenyItmet setAction: @selector(revealToggle:)]; 
    [self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer]; 
} 

在那之后,我叫Get方法在viewDidLoad中:

[self GetQUIZ]; 

方法详细信息:

- (void)GetQUIZ { 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
NSString *url = [NSString stringWithFormat:@"http://stringlearning.com/api/v1/user-quiz?token=%@",[[NSUserDefaults standardUserDefaults] stringForKey:@"token"]]; 

[request setURL:[NSURL URLWithString: url]]; 
[request setHTTPMethod:@"GET"]; 
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 
[request setValue:[UIDevice currentDevice].name forHTTPHeaderField:@"device"]; 

NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
NSLog(@"Left menu, User details: %@", [[NSString alloc] initWithData:[request HTTPBody] encoding:NSUTF8StringEncoding]); 
NSLog(@"%@", [request allHTTPHeaderFields]); 

if(conn) { 
    NSLog(@"Connection Successful"); 
} else 
    NSLog(@"Connection could not be made"); 

然后我用数据in connectionDidFinishLoading:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
NSError *deserr = nil; 
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:responseData options: 0 error: &deserr]; 

我读过,我应该使用异步方法,但我从来没有使用过。你会写一些细节解决方案吗? 也许,有不同的道路吗? 我将非常感谢您的帮助!

我建议从NSURLSession开始,这是一个现代的API,可以异步完成同样的事情。

要使用NSURLSession,你需要几个一块拼图:

  1. 网址到达,和任选的任何有效载荷或自定义页眉。
  2. NSURL一个实例:你的出发和下载的NSURLRequest把它包在
  3. NSURLSessionConfiguration,它处理的东西比如缓存,证书和超时。
  4. 会话本身。
  5. 您需要一个NSURLSessionTask实例。这是您的NSURLConnection最接近的对象。它通过代理或完成块具有回调,如果您只需要知道何时完成。

这里是如何做到这一点看在代码:

// 1. The web address & headers 
NSString *webAddress = [NSString stringWithFormat:@"http://stringlearning.com/api/v1/user-quiz?token=%@",[[NSUserDefaults standardUserDefaults] stringForKey:@"token"]]; 

NSDictionary <NSString *, NSString *> *headers = @{ 
                @"device" : [UIDevice currentDevice].name, 
                @"Content-Type" : @"application/x-www-form-urlencoded" 
                }; 

// 2. An NSURL wrapped in an NSURLRequest 
NSURL* url = [NSURL URLWithString:webAddress]; 
NSURLRequest *request = [NSURLRequest requestWithURL:url]; 

// 3. An NSURLSession Configuration 
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; 
[sessionConfiguration setHTTPAdditionalHeaders:headers]; 

// 4. The URLSession itself. 
NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:sessionConfiguration]; 

// 5. A session task: NSURLSessionDataTask or NSURLSessionDownloadTask 
NSURLSessionDataTask *dataTask = [urlSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 

}]; 

// 5b. Set the delegate if you did not use the completion handler initializer 
// urlSession.delegate = self; 

// 6. Finally, call resume on your task. 
[dataTask resume]; 

这将异步运行,让您的用户界面保持响应为您的应用程序加载的数据。

+0

为了简化这一点,您可以跳过自定义会话和会话配置的创建,只依赖'sharedSession'。 –

+0

谢谢!!!这真的很有用! – rmnbozhchenko

当您在主线程上发送请求时(就像您现在正在执行的操作),始终在主线程上执行的UI会被阻止,等待请求完成并处理。所以你应该在后台线程上异步执行你所有的网络。我会建议首先检查网络库AFNetworking,它可以简化大部分网络问题。

欢迎来到SO。您应该知道NSURLConnection在iOS 9中已被弃用。您应该使用NSURLSession。该方法非常相似。你可以把你创建的NSURLRequest传递给为异步请求设置的sharedSession对象。处理它最简单的方法是使用呼叫dataTaskWithRequest:completionHandler:,它采用完成块。在你的完成块中,你提供了处理成功和失败的代码。