异步 NSURLConnection 方案教程

3

我正在寻找一份关于使用NSURLConnection异步请求的好教程。我在stackoverflow和Google上寻找过,但没有找到。这可能是与此类似的无数问题的重复。但请指导我正确的教程,我以前使用过ASIHTTPRequest,但以前没有使用过苹果提供的库。


你有什么不理解的地方吗?本质上,它只涉及几个方法... - jrturton
是的,我正在尝试理解这个方法sendAsynchronousRequest:queue:completionHandler:。那么我应该如何通知请求已经被处理了呢?这个completionHandler到底是做什么的?这是处理异步请求的正确方法吗?还是有其他方法可供选择? - user2070420
是的,使用那种方式或委托方法都可以。你是否熟悉块? - jrturton
你能解释一下委托方法的好处吗?如果我不想使用sendAsynchronousRequest:queue:completionHandler:方法,我应该使用哪个方法?我对块不熟悉。 - user2070420
更新了我的回答,如果你想要委托,那不会很快,自从Objective-C引入块以来,我就一直讨厌在NSURLConnection中使用它们。 - Holyprin
@jrturton 当我使用sendAsynchronousRequest:queue:completionHandler:这个方法时,有没有一种实现超时和取消请求的方式? - user2070420
1个回答

6

我可以为你提供一种自己写的方案,但是我强烈推荐使用AFNetworking。它是NSURConnection / NSURLRequest系统的一个封装,流程更加清晰,而且还支持基本的NSURLRequests / Connections和常规的NSOperationQueues。该库还使用cocoa pods,而且真的非常简洁易用。

NSOperationQueue *mainQueue = [[NSOperationQueue alloc] init];
[mainQueue setMaxConcurrentOperationCount:5];

NSURL *url = [NSURL URLWithString:@"http://192.168.0.63:7070/api/Misc/GetFuelTypes"];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];

[request setHTTPMethod:@"GET"];
[request setAllHTTPHeaderFields:@{@"Accepts-Encoding": @"gzip", @"Accept": @"application/json"}];

[NSURLConnection sendAsynchronousRequest:request queue:mainQueue completionHandler:^(NSURLResponse *response, NSData *responseData, NSError *error) {
    NSHTTPURLResponse *urlResponse = (NSHTTPURLResponse *)response;
    if (!error) {
        NSLog(@"Status Code: %li %@", (long)urlResponse.statusCode, [NSHTTPURLResponse localizedStringForStatusCode:urlResponse.statusCode]);
        NSLog(@"Response Body: %@", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);
    }
    else {
        NSLog(@"An error occured, Status Code: %i", urlResponse.statusCode);
        NSLog(@"Description: %@", [error localizedDescription]);
        NSLog(@"Response Body: %@", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);
    }
}];

主队列对象用于路由请求和管理同时可以发送的请求数量。这可以用于许多方式,我倾向于将它们用于分类请求(身份验证、主要、上传队列)。
一旦进入块内,您就可以使用返回的响应构建本地NSHTTPURLResponse。如果您想要返回状态代码,则需要这个。(在标准NSURLResponse对象中不存在)
responseData是数据,通常可以直接转换为字符串或通过反序列化运行以获取人类可读数据。
简单来说,如果您不知道如何从同一对象管理多个请求,那么代理会让您陷入麻烦(这可能是我喜欢块的原因):-)
像往常一样,代理或块会在收到响应后触发UI更新,但不会被阻塞等待请求完成。如果您正在将数据加载到表格中,则会在加载时调用请求并提供某种形式的进度hud告诉用户正在进行请求,一旦接收到数据,您就会删除hud并重新加载表格数据。HUD必须在主线程上调用,因此您肯定需要处理它,我通常只构建扩展并使用performSelectorOnMainThread,但更好的方法可能是在dispatch_async中包装函数,并在外部调用您的hud show / hide代码。

谢谢Holyprin,我知道AFNetworking和ASIHTTPRequest。但是我不允许使用第三方库,这就是我试图从头开始的原因。如果您能提供给我您的教程,那将非常棒。 - user2070420
我猜那很有道理,我会在这里写一篇文章。 - Holyprin
我该如何通知我的用户界面任务已经完成,比如我正在下载一些图像,让它更新自身。 - user2070420
使用 performSelectorOnMainThread / performSelector 和 [object setTarget:forControlEvents:] 来在 UIControl 类型对象上执行操作,甚至使用 GCD,有很多方法可以通知主线程更新用户界面。 - Holyprin
有取消请求的规定吗?从StackoverFlow的讨论来看,似乎不可能。还有超时的方法吗? - user2070420

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接