Reputation: 7215
I currently use a delegate, calling it APIDelegate
to handle API-related requests from my View Controllers. The excerpt from the delegate looks like this (Swift):
init(delegate: APIDelegateProtocol?) {
self.delegate = delegate
}
func get(url: String, params: NSDictionary?) {
...blah blah...
let manager = AFHTTPSessionManager(baseURL: baseURL, sessionConfiguration: sessionConfig)
manager.GET(
url,
parameters: params,
success: { (task: NSURLSessionDataTask!, responseObject: AnyObject!) in
let httpResponse: NSHTTPURLResponse = task.response as NSHTTPURLResponse
if httpResponse.statusCode == 200 {
self.delegate?.didReceiveAPIResults(responseObject as NSDictionary)
} else {
NSLog("GET Error -> Code: \(httpResponse.statusCode), Msg: \(responseObject)")
}
},
failure: { (task: NSURLSessionDataTask!, error: NSError!) in
dispatch_async(dispatch_get_main_queue(), {
UIAlertView(title: "Networking Error", message: "GET Error -> \(url) -> \(error.localizedDescription)", delegate: nil, cancelButtonTitle: "OK").show()
}
)
}
)
}
However, according to NSScreenCast episode on AFNetworking 2.0 and a few other web tutorials, they seem to recommend to create Singleton that is subclassed from AFHTTPSessionManager
, something like this (copy & pasted in Obj-C):
+ (ITunesClient *)sharedClient {
static ITunesClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURL *baseURL = [NSURL URLWithString:@"https://itunes.apple.com/"];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
[config setHTTPAdditionalHeaders:@{ @"User-Agent" : @"TuneStore iOS 1.0"}];
NSURLCache *cache = [[NSURLCache alloc] initWithMemoryCapacity:10 * 1024 * 1024
diskCapacity:50 * 1024 * 1024
diskPath:nil];
[config setURLCache:cache];
_sharedClient = [[ITunesClient alloc] initWithBaseURL:baseURL
sessionConfiguration:config];
_sharedClient.responseSerializer = [AFJSONResponseSerializer serializer];
});
return _sharedClient;
}
My question is:
What is the advantage of using a Singleton subclass of AFHTTPSessionManager
versus just calling AFHTTPSessionManager
directly within the APIDelegate
? Is it better for memory management? Isn't AFHTTPSessionManager
already non-blocking with respect to the View Controller (the call is asynchronous)?
Upvotes: 0
Views: 1982
Reputation: 66242
Isn't
AFHTTPSessionManager
already non-blocking with respect to the View Controller (the call is asynchronous)?
Yes, both approaches are non-blocking.
What is the advantage of using a Singleton subclass of
AFHTTPSessionManager
versus just callingAFHTTPSessionManager
directly within theAPIDelegate
? Is it better for memory management?
There are no significant memory differences. (The only relevant difference is that you could deallocate an APIDelegate
instance, but a singleton will hang around for the lifetime of the app.)
One advantage of a subclass over the approach you're taking is that you might have a view controller with more than one possible API call. However, in this case both responses would result in a call to didReceiveAPIResults
, which would then need to try to figure out which API call was just responded to. This can be error prone, since network requests don't always return in the order they're made.
If you take the singleton approach, your manager can still hide all of the networking from your view controller.
For example, if you're writing an app that lists cheeses for sale, your header file could include:
- (void)getCheeseListWithSuccess:(void (^)(NSArray *cheeses))success
failure:(void (^)(NSError *error))failure;
This hides the data source from your view controller, which shouldn't care if it came from an on-disk cache, the Internet, or a random cheese generator.
To answer your question more succinctly, neither solution is formally incorrect, but a solution that uses completion handlers instead of delegation is probably better.
Upvotes: 4