93

With work having recently stopped on ASIHTTPRequest, it seems like attention is shifting to AFNetworking.

However, I've not yet found a good comparison of the features of the two libraries, so I don't know what I might lose if/when I switch over.

Major differences I've spotted so far are:

  1. AFNetworking has a much smaller code size (which is good)
  2. AFNetworking is being rapidly improved (so it may not yet be mature, may not have a stable API yet?)
  3. Both seem to have caching, though I've seen hints that because AFNetworking uses NSURLConnection it won't cache objects over 50K
  4. ASIHTTPRequest has very good support for manual & automatic (PAC) http proxies; I can't find any information on what level of support AFNetworking has for proxies
  5. AFNetworking requires iOS 4+, whereas ASIHTTPRequest works right back to iOS 2 (not really an issue for me, but it is an issue for some people)
  6. AFNetworking doesn't (yet) have a built in persistent cache, but there's a persistent cache which has a pending pull request: https://github.com/gowalla/AFNetworking/pull/25

Has anyone seen any good comparisons of the two libraries or any documented experiences of switching from one to the other?

Community
  • 1
  • 1
JosephH
  • 37,173
  • 19
  • 130
  • 154
  • AFNetworking lacks of very detailed documentation and examples so I can't say much about it. The major reason I use ASIHTTPRequest because it supports iOS 3.0 and `ASIFallbackToCacheIfLoadFailsCachePolicy` is very good. And, I think AFNetworking has no persistent cache support. This is a no-go for me. – iwat Sep 28 '11 at 09:28
  • Just notice that you are the first one who tags question with `afnetworking`. – iwat Sep 28 '11 at 09:34
  • There is a cache that's waiting to be pulled into AFNetworking, I've added a link into my question. – JosephH Sep 28 '11 at 11:27
  • 1
    @iwat AFNetworking fully supports `NSURLCache`. If you're looking for disk cache, I'd heartily suggest [Peter Steinberger's SDURLCache fork](https://github.com/steipete/SDURLCache). – mattt Oct 25 '11 at 13:56
  • 2
    Have you tried my networking framework MKNetworkKit ? http://blog.mugunthkumar.com/products/ios-framework-introducing-mknetworkkit/ Basic, Digest and NTLM Authentication, auto-caching, built-in image caching, super easy file upload support, excellent documentation are some of the pluses. – Mugunth Dec 14 '11 at 16:10

8 Answers8

59

I loved ASIHTTPRequest and I was sad to see it go. However, the developer of ASI was right, ASIHTTPRequest has become so large and bloated that even he couldn't devote time to bring it to par with newest features of iOS and other frameworks. I moved on and now use AFNetworking.

That said, I must say that AFNetworking is much more unstable than ASIHTTP, and for the things I use it for, it needs refinement.

I often need to make HTTP requests to 100 HTTP sources before I display my results on screen, and I have put AFHTTPNetworkOperation into an operation queue. Before all results are downloaded, I want to be able to cancel all operations inside the operation queue and then dismiss the view controller that holds the results.

That doesn't always work.

I get crashes at random times with AFNetworking, while with ASIHTTPRequest, this operations were working flawlessly. I wish I could say which specific part of AFNetworking is crashing, as it keeps crashing at different points (however, most of these times the debugger points to the NSRunLoop that creates an NSURLConnection object). So, AFNetworking needs to mature in order to be considered as complete as ASIHTTPRequest was.

Also, ASIHTTPRequests supports client authentication, which AFNetworking lacks at the moment. The only way to implement it is to subclass AFHTTPRequestOperation and to override NSURLConnection's authentication methods. However, if you start getting involved with NSURLConnection, you will notice that putting NSURLConnection inside an NSOperation wrapper and writing completion blocks isn't so hard as it sounds and you will start thinking what keeps you from dumping 3rd party libraries.

ASI uses a whole different approach, since it uses CFNetworking (lower-level foundation frameworks based on C) to make downloading and file uploading possible, skipping NSURLConnection completely, and touching concepts most of us OS X and iOS developers are too afraid to. Because of this, you get better file uploading and downloading, even web page caches.

Which do i prefer? It's hard to say. If AFNetworking matures enough, I will like it more than ASI. Until then, I can't help but admire ASI, and the way it became one of the most used frameworks of all time for OS X and iOS.

EDIT: I think it's time to update this answer, as things have changed a bit after this post.

This post was written some time ago, and AFNetworking has matured enough. 1-2 months ago AF posted a small update for POST operations that was my last complaint about the framework (a small line ending fault was the reason that echonest uploads failed with AF but were completed fine with ASI). Authentication is not an issue with AFnetworking, as for complex authentication methods you can subclass the operation and make your own calls and AFHTTPClient makes basic authentication a piece of cake. By subclassing AFHTTPClient you can make an entire service consumer in little time.

Not to mention the absolutely necessary UIImage additions that AFNetworking offers. With blocks and custom completion blocks and some clever algorithm, you can make table views with asynchronous image downloading and cell filling pretty easily, whereas in ASI you had to make operation queues for bandwidth throttling and mind yourself to cancel and resume the operation queue according to table view visibility, and stuff like that. Development time of such operations has been halved.

I also love the success and failure blocks. ASI has only a completion block (which is actually the completion block of NSOperation). You had to check whether you had an error on completion and act accordingly. For complex web services, you could get lost in all the "ifs" and "elses"; In AFNetworking, things are much more simple and intuitive.

ASI was great for its time, but with AF you can change the way you handle web services completely in a good way, and make scalable applications more easily. I really believe that there is no reason whatsoever to stick with ASI anymore, unless you want to target iOS 3 and below.

peakingcube
  • 1,388
  • 15
  • 32
csotiriou
  • 5,653
  • 5
  • 36
  • 45
  • 1
    +1 very insighful. Perhaps it's worth posting your crashes as a question on stackoverflow? I'd be interested to see more detail. – JosephH Dec 04 '11 at 20:07
  • Thanks. When I have concrete data about the crashes I will do that. – csotiriou Dec 05 '11 at 17:55
  • 3
    Is the stability issue still an issue? – Johan Karlsson Jan 24 '12 at 11:28
  • 1
    On a preliminary data based on tests I ran some days ago, no. It's not. However, even with the latest version of the framework, I have an example that crashes sometimes on the run loop of AFURLConnection when stressed enough with a series of actions under certain conditions (allocate/cancel immediately/deallocate/reallocate/start). It must have something to do with NSOperation completion blocks and NSRunLoop though. I have checked the implementation of AFNetworking and couldn't find a cause about it. – csotiriou Jan 24 '12 at 11:56
  • ASI does have a failure block. – Kekoa Aug 13 '12 at 16:44
  • AFNetworking lacks download speed throttling, while ASIHTTPRequest does have that. BTW AFNetworking have upload speed throttling. – bikram990 Sep 20 '13 at 06:55
  • it doesnt support proxy servers... or at least i have no idea how to do it. – João Nunes Mar 25 '14 at 09:31
17

Just finishing up a project where I'm using AFNetworking instead of ASI. Have used ASI on previous projects; it's been a great help in the past.

Here's what AFNetworking is missing (as of today) that you should know about:

  • Nothing

ASI is going away. Use AF now. It's small, it works, and it's going to continue to be supported. It's also organized more logically, especially for API clients. It has a number of great classes for oft-used special cases like asynchronous loading of images in table views.

Jeff
  • 4,751
  • 5
  • 31
  • 35
  • 9
    As @iwat mentioned in the commants on the question, AFNetworking is missing robust caching. That's interesting and relevant to the question, so "nothing" is the wrong answer. Other than that, I agree completely with your sentiment, tho. – Kenny Winker Sep 30 '11 at 00:23
  • 1
    @KennyWinker Please see my reply in that comment thread. I'm happy to say that AFNetworking doesn't build in a cache by design. Rather, one is free to swap in their favorite `NSURLCache`-based solution. – mattt Oct 25 '11 at 13:57
  • 1
    on Nothing part - how i can use proxies in the requests ? – Alex Volovoy Nov 23 '11 at 21:48
  • @AlexVolovoy you're probably best to ask that as a new question – JosephH Dec 03 '11 at 11:19
  • I wouldn't say 'nothing'. Please see my answer below. – borisdiakur Jan 03 '12 at 14:30
  • yeah proxy is lacking. that is why im still using ASI. – João Nunes Mar 25 '14 at 09:32
  • How to use proxy urls in AFNetworking? I've url like http://100.1.100.1:5000/testdata/test/xyz.php?format=json – Gajendra K Chauhan Jan 21 '16 at 07:07
4

AFNetworking doesn't support clientCertificateIdentity and clientCertificates for TLS client authentication.

We can do that with the - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge method in a subclass of AFURLConnectionOperation but it's not as easy.

Mathieu Hausherr
  • 3,485
  • 23
  • 30
  • 5
    You can now do `setAuthenticationChallengeBlock:` on `AFURLConnectionOperation` and its subclass, and pass in the logic to handle any authentication challenges as you need, without having to subclass. – mattt Jan 22 '12 at 19:22
2

AFNetwork lacks the ability to upload large files. It assumes file content is in RAM. ASI was smart enough to simply stream file content from disk.

December
  • 584
  • 5
  • 10
2

I've been using ASI* for a while now and I absolutely love the fileupload approach of ASI, and though I am excited to jump to AFNetworking, fileupload support in AfNetworking is not as easy to use compared to ASI*.

Teo Choong Ping
  • 12,512
  • 18
  • 64
  • 91
2

Until now I couldn't figure out how to set a timeout with AFNetworking when doing a synchronous POST request. UPDATE: I finally figured out: https://stackoverflow.com/a/8774125/601466
Now switching to AFNetworking : ]

==================

Apple overrides the timeout for a POST, setting it to 240 seconds (in case it was set shorter then the 240 seconds), and you can't change it. With ASIHTTP you just set a timeout and it works.

A code example with a synchronous POST request:

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;

I tried to set a timeout here, but nothing worked. This issue keeps me from migrating to AFNetworking.

See also here: How to set a timeout with AFNetworking

Community
  • 1
  • 1
borisdiakur
  • 10,387
  • 7
  • 68
  • 100
  • Your point about timeouts is good, thanks for sharing! I don't understand how this relates to making requests syncronously though, can you expand on that? – JosephH Jan 03 '12 at 15:30
  • @JosephH You are right. Of course sometimes you also need to set a timeout when doing asynchronous requests. I have updated my answere : ] – borisdiakur Jan 03 '12 at 16:07
  • Apple fixed the issue with timeoutInterval not being able to be less than 240 seconds, however this is still an issue as even if you set the timeoutInterval, the request does not respect it somehow. – Jasper Apr 22 '14 at 12:26
0

In ASIHTTP I loved that I could attach a userinfo dictionary to individual requests. As far as I see there is no direct support for this in AFHTTPRequestOperation. Has anyone come up with an elegant workaround yet? Apart from the trivial subclassing of course.

Lvsti
  • 1,525
  • 15
  • 15
  • 2
    Don't ask questions in answers, your chances for getting reponse is very very low. Use either comment or new question instead ;) – Michal Feb 21 '13 at 14:28
-8

AFNetworking works with "blocks" which is more natural for me than working with delegates like ASIHTTPRequest does.

Working with blocks it's like working with Anonymous Function in javascript.

torhector2
  • 443
  • 1
  • 5
  • 19