Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing NSURLConnection with NSURLSession

I have been starting a design for NetworkCommunication. I had a design where NSOperation subclasses create and manage their own NSURLConnection. The NSOperation subclass is instantiated by a NetworkManger class which adds it to the NSOperationQueue. Once the request is finished the delegate(ex:ViewController will be called). This is the flow:

The Network Manger instantiates NSOperation subclass (which encapsulates URL, parameters etc) and adds it to a NSOperationQueue it maintains. NSOperation subclass instantiates NSURLConnection (which performs asynchronous request and retrieves data) NSURLConnection dumps data to NSOperation-subclass NSOperation-subclass executes the completion block supplied by the delegate( view controller). I'm trying to implement the same pattern with NSURLSession now. I want to be able to encapsulate the url and parameters required to make a network request inside a single object.

Is it fine if i use the same pattern if I use NSURLSession. I checked AFNetworking classes. But, they have not subclassed NSOperation for NSURLSession. And, moreover where should the session object go. Will it be a part of the NSOperation class.

Can someone give some expert advice on this. I should be able to cancel requests, do uploading(POST/PUT), downloading of data. The Network Manager class would be the single point of contact for any network request.

like image 641
user694688 Avatar asked Jun 09 '14 05:06

user694688


1 Answers

Update:

NSURLConnection is deprecated effective Mac OS 10.11 and iOS 9. So, at this point NSURLSession should be used in lieu of NSURLConnection. As the NSURLConnection.h header says:

Deprecated: The NSURLConnection class should no longer be used. NSURLSession is the replacement for NSURLConnection.

My original answer is below.


The answer depends upon whether you need the richness of the various NSURLSession delegate methods or not. If you're ok using the completion block renditions (i.e. no progress callbacks, no streaming, etc.), the conversion from NSURLConnection to NSURLSession is pretty trivial. Just put your NSURLSession instance in your NetworkManager class, and then wrap the delegate based NSURLSessionTask instances in a concurrent NSOperation subclass and you're done. Just adopt the standard asynchronous/concurrent NSOperation subclass pattern.

If you're using the delegate-based renditions of NSURLSession, it's a whole different kettle of fish. The main hassle is that the various NSURLSessionTask delegate methods are called on the session delegate rather than a task delegate object. At first blush, this might sound like it's a trivial issue, but if your operation instances have unique completion/progress blocks, for example, you're stuck with the hassle of how to have the session object map these delegate method callbacks to the individual original request operation instances.

To tackle this, you have to maintain a mapping of task identifiers to your NSOperation subclass objects. You can then implement these NSURLSessionTask (including task, download task, and upload task) delegate methods at the respective NSOperation subclass. The NSURLSession network manager class can then, when it receives a NSURLSessionTask delegate call, use the task identifier to identify the appropriate NSOperation instance, and then call the appropriate delegate method there.

Finally, if you intend to handle background NSURLSession instances, life gets even more difficult (because background tasks will continue even after your app has terminated and all of its objects have been discarded). Background sessions simply don't lend themselves to an NSOperation-based approach.

Bottom line, this is trivial if you only need the completion-block NSURLSession methods, but it's a bit of a hassle if you need the delegate-based rendition.

like image 135
Rob Avatar answered Oct 12 '22 11:10

Rob