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

Posted

技术标签:

【中文标题】在 NSURLConnection 加载数据时执行一些任务objective-c【英文标题】:Perform some task while NSURLConnection loading data objective-c 【发布时间】:2016-01-20 21:15:59 【问题描述】:

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

这是我在 viewDidLoad 中的 SWR:

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

之后,我在 viewDidLoad 中调用了 Get 方法:

[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");

然后我在connectionDidFinishLoading中使用数据:

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

我读到我应该使用异步方法,但我以前从未使用过它。你会写一些详细的解决方案吗? 也许,有不同的路径吗? 非常感谢您的帮助!

【问题讨论】:

【参考方案1】:

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

要使用 NSURLSession,您需要解决一些问题:

    要访问的网址,以及可选的任何有效负载或自定义标头。 NSURL 的实例:您从中下载的位置以及用于包装它的 NSURLRequest。 NSURLSessionConfiguration,用于处理缓存、凭据和超时等事务。 会话本身。 您需要一个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];

这将异步运行,让您的 UI 在您的应用加载数据时保持响应。

【讨论】:

为了简化这一点,您可以跳过自定义会话和会话配置的创建,只依赖sharedSession【参考方案2】:

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

【讨论】:

【参考方案3】:

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

【讨论】:

以上是关于在 NSURLConnection 加载数据时执行一些任务objective-c的主要内容,如果未能解决你的问题,请参考以下文章

停止/中止 NSURLConnection

如何从 NSURLConnection 委托发送多个 url 请求?

尝试使用 Alamofire 下载图像时,NSURLSession/NSURLConnection HTTP 加载失败

NSURLConnection HTTP 加载失败(kCFStreamErrorDomainSSL,-9813)[重复]

NSURLSession/NSURLConnection HTTP 加载失败 (kCFStreamErrorDomainSSL, -9802) 错误

Xcode 7.3:NSURLSession/NSURLConnection HTTP 加载失败(kCFStreamErrorDomainSSL,-9802)