AFNetworking缺少哪些主要的ASIHTTPRequest功能?

93

最近,由于ASIHTTPRequest的开发停止,似乎人们的注意力转向了AFNetworking

然而,我还没有找到一个好的比较这两个库特性的文章,所以我不知道如果我要切换到AFNetworking会失去什么。

到目前为止,我发现主要的区别有:

  1. AFNetworking的代码体积更小(这是好的)
  2. AFNetworking正在快速改进(因此它可能还不够成熟,API也可能不太稳定?)
  3. 两者都似乎有缓存,尽管我看到过的一些暗示表明,因为AFNetworking使用了NSURLConnection,它不会缓存超过50K的对象
  4. ASIHTTPRequest对手动和自动(PAC)HTTP代理的支持非常好;我找不到任何有关AFNetworking对代理的支持程度的信息
  5. AFNetworking需要iOS 4+,而ASIHTTPRequest适用于iOS 2及以上版本(对我来说不是问题,但对一些人来说是问题)
  6. AFNetworking尚未内置持久性缓存,但有一个挂起的拉取请求: https://github.com/gowalla/AFNetworking/pull/25

是否有人看过这两个库的好比较或者有任何从一个库切换到另一个库的经验文档?


AFNetworking缺乏非常详细的文档和示例,因此我无法对其进行评价。我使用ASIHTTPRequest的主要原因是它支持iOS 3.0,并且ASIFallbackToCacheIfLoadFailsCachePolicy非常好用。而且,我认为AFNetworking没有持久缓存支持,这对我来说是不能接受的。 - iwat
刚注意到你是第一个使用“afnetworking”标签的人。 - iwat
有一个缓存正在等待被拉入AFNetworking,我已经在我的问题中添加了一个链接。 - JosephH
1
@iwat AFNetworking完全支持NSURLCache。如果您正在寻找磁盘缓存,我强烈建议使用Peter Steinberger的SDURLCache分支 - mattt
2
你尝试过我的网络框架MKNetworkKit吗? http://blog.mugunthkumar.com/products/ios-framework-introducing-mknetworkkit/ 基本、摘要和NTLM身份验证、自动缓存、内置图像缓存、超级简单的文件上传支持以及优秀的文档是其中的一些优点。 - Mugunth
8个回答

59
我非常喜欢ASIHTTPRequest,很遗憾它已经停止更新了。但是ASI的开发者说得没错,ASI已经变得过于庞大臃肿,即使他也无法抽出时间来将其与最新的iOS和其他框架保持同步。我现在使用AFNetworking。
尽管如此,我必须说,相比于ASIHTTP,AFNetworking更不稳定,并且在我使用它进行的某些操作中需要改进。
我经常需要在显示结果之前向100个HTTP源发起HTTP请求,并将AFHTTPNetworkOperation放入操作队列中。在下载所有结果之前,我希望能够取消操作队列中的所有操作,然后关闭持有结果的视图控制器。
但这并不总是有效。
使用AFNetworking时,在随机一些时间会崩溃,而对于ASIHTTPRequest,这些操作可以完美地运行。我希望我能够确定AFNetworking中导致崩溃的具体部分,因为它总是在不同的点崩溃(然而,大多数情况下调试器指向创建NSURLConnection对象的NSRunLoop)。所以,AFNetworking需要成熟才能像ASIHTTPRequest一样完整。
此外,ASIHTTPRequests支持客户端身份验证,而AFNetworking目前缺乏此功能。唯一的实现方法是子类化AFHTTPRequestOperation并覆盖NSURLConnection的身份验证方法。但是,如果你开始涉足NSURLConnection,你会发现将NSURLConnection放入NSOperation包装器并编写完成块并不像听起来那么难,并且你会开始考虑要不要放弃第三方库。
ASI使用了一种完全不同的方法,因为它使用CFNetworking(基于C的低级基础框架)实现了下载和文件上传,完全跳过了NSURLConnection,并触及大多数我们这些OS X和iOS开发人员害怕的概念。正因为如此,你可以获得更好的文件上传和下载,甚至是网页缓存。
我更喜欢哪一个呢?很难说。如果AFNetworking成熟了,我会比ASI更喜欢它。在此之前,我只能欣赏ASI,以及它成为OS X和iOS历史上最常用的框架之一的方式。我认为现在是更新这篇答案的时候了,因为此贴发布后事情有点变化。

这篇文章写于一段时间前,AFNetworking 已经足够成熟。1-2个月前,AF发布了一个关于 POST 操作的小更新,这是我对框架的最后一点抱怨(一个小行尾错误是导致 echonest 上传失败的原因,但使用 ASI 没问题)。对于 AFnetworking,身份验证不是问题,对于复杂身份验证方法,您可以子类化操作并进行自己的调用,AFHTTPClient 让基本身份验证变得轻而易举。通过子类化 AFHTTPClient,您可以在很短的时间内制作整个服务消费者。

更不用说 AFNetworking 提供的非常必要的 UIImage 添加功能了。利用块和自定义完成块以及一些聪明的算法,您可以相当容易地制作具有异步图像下载和单元格填充的表视图,而在 ASI 中,您需要制作操作队列以实现带宽限制,并自行取消和恢复操作队列,根据表视图的可见性进行操作,等等。这样的操作开发时间已经减半。

我也喜欢成功和失败块。ASI 只有一个完成块(实际上是 NSOperation 的完成块)。您必须在完成时检查是否有错误并相应地采取行动。对于复杂的 Web 服务,您可能会在所有“如果”和“否则”中迷失方向;在 AFNetworking 中,事情要简单得多,也更加直观。

ASI 在其时代是很棒的,但是通过 AF,您可以以好的方式彻底改变您处理 Web 服务的方式,并更轻松地制作可扩展的应用程序。我真的相信,除非您想针对 iOS 3 及以下版本,否则没有任何理由再坚持使用 ASI。


1
+1非常有见地。也许把你的崩溃问题发布到stackoverflow上会更值得一试?我很想看到更多细节。 - JosephH
3
稳定性问题仍然存在吗? - Johan Karlsson
1
根据我几天前运行的测试所得到的初步数据,答案是否定的。然而,即使使用最新版本的框架,我仍然有一个例子,在特定条件下(立即分配/取消/释放/重新分配/启动)进行一系列操作时,AFURLConnection 的运行循环有时会崩溃。这一定与 NSOperation 完成块和 NSRunLoop 有关。我已经检查了 AFNetworking 的实现,但没有找到原因。 - csotiriou
AFNetworking缺乏下载速度限制,而ASIHTTPRequest具有该功能。顺便提一下,AFNetworking具有上传速度限制。 - bikram990
它不支持代理服务器... 或者至少我不知道如何做。 - João Nunes
显示剩余2条评论

17

我刚完成一个项目,使用的是AFNetworking而非ASI。之前在其它项目中使用了ASI,它曾经是很有帮助的。

以下是AFNetworking目前缺失的特性:

  • 没有

由于ASI即将停止维护,建议立即转用AF。AF小巧实用且持续得到支持。与API客户端特别有关的类组织方式更为合理。此外,它还包含了许多对于常见情况有用的类,例如异步加载表格视图中的图像。


9
正如@iwat在评论中提到的,AFNetworking缺乏强大的缓存功能。这很有趣,也与问题相关,因此“没有任何东西”是错误的答案。除此之外,我完全同意您的观点。 - Kenny Winker
1
@KennyWinker 请查看我在那个评论线程中的回复。很高兴地说,AFNetworking 的设计并没有内置缓存。相反,我们可以自由地使用自己喜欢的基于 NSURLCache 的解决方案。 - mattt
1
在“Nothing”部分中,我如何在请求中使用代理? - Alex Volovoy
是的,代理功能不够完善。这就是为什么我仍在使用ASI的原因。 - João Nunes
如何在AFNetworking中使用代理URL?我有一个类似于http://100.1.100.1:5000/testdata/test/xyz.php?format=json的URL。 - Gajendra K Chauhan
显示剩余2条评论

4

AFNetworking不支持使用clientCertificateIdentity和clientCertificates进行TLS客户端身份验证。

我们可以通过在AFURLConnectionOperation的子类中使用- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge方法来实现,但这样做并不容易。


5
现在您可以在 AFURLConnectionOperation 及其子类中使用 setAuthenticationChallengeBlock: 方法,并传入处理任何身份验证挑战逻辑的代码,而无需进行子类化。该方法允许您自定义身份验证处理方式,保持原意不变,同时使内容更易于理解。 - mattt

2
直到现在,我仍然无法弄清楚如何在进行同步POST请求时使用AFNetworking设置超时。更新:我终于明白了:https://dev59.com/SGsy5IYBdhLWcg3w0RM5#8774125。现在转向使用AFNetworking :]
================== 苹果公司覆盖了POST的超时时间,将其设置为240秒(如果设置的时间短于240秒),您无法更改它。使用ASIHTTP,您只需设置一个超时时间即可。以下是一个同步POST请求的代码示例:
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
                                @"doSomething", @"task",
                                @"foo", @"bar",
                                nil];

AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:baseURL]];

NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" path:requestURL parameters:params];
[httpClient release];

AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NDLog(@"fail! %@", [error localizedDescription]);
}];

NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
[[AFNetworkActivityIndicatorManager sharedManager] incrementActivityCount];

[queue addOperation:operation];
[queue waitUntilAllOperationsAreFinished]; // Stuck here for at least 240 seconds!

[[AFNetworkActivityIndicatorManager sharedManager] decrementActivityCount];
if (![[operation responseString] isEqualToString:@""]) {
    return [operation responseString];
}

return nil;

我尝试在这里设置了一个超时时间,但没有任何作用。这个问题让我无法迁移到AFNetworking。

另请参阅: 如何使用AFNetworking设置超时时间


你提到超时的观点很好,谢谢分享!但我不明白这与同步请求有什么关系,你能详细解释一下吗? - JosephH
@JosephH 你是对的。当进行异步请求时,有时候也需要设置超时时间。我已经更新了我的回答:] - borisdiakur
苹果已经修复了timeoutInterval不能小于240秒的问题,但是这仍然是一个问题,因为即使您设置了timeoutInterval,请求也不会以某种方式尊重它。 - Jasper

2

AFNetwork缺乏上传大文件的能力,它假设文件内容在内存中。 ASI则聪明地从磁盘上直接流式传输文件内容。


2

我已经使用ASI*一段时间了,非常喜欢ASI的文件上传方式,虽然我很兴奋地转向AFNetworking,但与ASI*相比,AFNetworking的文件上传支持不太容易使用。


0
在ASIHTTP中,我喜欢能够将用户信息字典附加到单个请求上。就我所知,在AFHTTPRequestOperation中没有直接支持这一点。有人想出了一个优雅的解决方法吗?除了微不足道的子类化之外。

2
不要在答案中提问,你得到回复的机会非常非常低。请改用评论或新问题;) - Michal

-8

AFNetworking使用“blocks”与ASIHTTPRequest使用委托相比更自然。

使用块就像在JavaScript中使用匿名函数一样。


真的,但在我看来,这不是使用ASIHTTPRequest开发的主要方法。 - torhector2
7
这只是因为在编写ASIHTTP之后引入了blocks,我总是使用blocks与ASI一起使用,从不使用代理。 - hypercrypt

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