在 NSURLConnection 加载数据时执行一些任务 objective-c
Perform some task while NSURLConnection loading data objective-c
我是 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];
我读到我应该使用异步方法,但我以前从未使用过它。你会写一些详细的解决方案吗?
也许,有不同的路径?
非常感谢您的帮助!
我建议从 NSURLSession
开始,这是一个现代的 API,可以异步完成同样的事情。
要使用 NSURLSession,您需要解决几个问题:
- 要访问的网址,以及可选的任何负载或自定义 headers。
NSURL
的一个实例:您从哪里下载并用一个 NSURLRequest 来包装它。
- 一个
NSURLSessionConfiguration
,它处理诸如缓存、凭据和超时之类的事情。
- session 本身。
- 您需要一个
NSURLSessionTask
实例。这是离您的 NSURLConnection 最近的 object。如果您只需要知道它何时完成,它可以通过委托或完成块进行回调。
代码如下所示:
// 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 在应用加载数据时保持响应。
当您在主线程上发送请求时,就像您现在所做的那样,总是在主线程上执行的 UI 被阻塞,等待请求完成和处理。因此,您应该在后台线程上异步执行所有网络。我建议首先检查网络库 AFNetworking ,它可以简化您的大部分网络问题。
欢迎来到 SO。您应该知道 NSURLConnection 在 iOS 9 中已被弃用。您应该改用 NSURLSession。该方法非常相似。您可以获取已创建的 NSURLRequest 并将其传递给为异步请求设置的 sharedSession 对象。处理它的最简单方法是使用调用 dataTaskWithRequest:completionHandler:
,它需要一个完成块。在您的完成块中,您提供处理成功和失败的代码。
我是 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];
我读到我应该使用异步方法,但我以前从未使用过它。你会写一些详细的解决方案吗? 也许,有不同的路径? 非常感谢您的帮助!
我建议从 NSURLSession
开始,这是一个现代的 API,可以异步完成同样的事情。
要使用 NSURLSession,您需要解决几个问题:
- 要访问的网址,以及可选的任何负载或自定义 headers。
NSURL
的一个实例:您从哪里下载并用一个 NSURLRequest 来包装它。- 一个
NSURLSessionConfiguration
,它处理诸如缓存、凭据和超时之类的事情。 - session 本身。
- 您需要一个
NSURLSessionTask
实例。这是离您的 NSURLConnection 最近的 object。如果您只需要知道它何时完成,它可以通过委托或完成块进行回调。
代码如下所示:
// 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 在应用加载数据时保持响应。
当您在主线程上发送请求时,就像您现在所做的那样,总是在主线程上执行的 UI 被阻塞,等待请求完成和处理。因此,您应该在后台线程上异步执行所有网络。我建议首先检查网络库 AFNetworking ,它可以简化您的大部分网络问题。
欢迎来到 SO。您应该知道 NSURLConnection 在 iOS 9 中已被弃用。您应该改用 NSURLSession。该方法非常相似。您可以获取已创建的 NSURLRequest 并将其传递给为异步请求设置的 sharedSession 对象。处理它的最简单方法是使用调用 dataTaskWithRequest:completionHandler:
,它需要一个完成块。在您的完成块中,您提供处理成功和失败的代码。