MBTaskContainer
What is MBTaskContainer?
MBTaskContainer
is a simple class that lets you add your NSURLSessionTask
s into it and read active tasks from it safely.
Example scenario
Let's say your server use OAuth2
authentication standard, so you need to obtain a token before establishing a connection to access your API
And again, let's say your application has an architecture like the following:
ViewController
-> DataController
where
ViewController
- Typical
UIViewController
subclass - it may have an
UIButton
to cancel ongoing network operations
DataController
NSObject
subclass- responsible for making network calls
In that case, we cannot return actual ongoing network tasks to ViewController
from DataController
immediately as even a simple network request would be like the following:
ViewController
callsDataController
'sgetItems
methodDataController
makes the request- Request returns
401 Unauthorized
responsible DataController
makes another request to obtain a new token- After receiving new token,
DataController
retriesgetItems
request
In short, there will be many request that are done asynchronously and some follow the others.
In order to address this problem, you can use MBTaskContainer
!
Example solution
- Returns an
MBTaskContainer
instance fromDataController:getItems
. - Whenever a new network task is created, add it to returned instance.
ViewController
can access active network tasks at any time.
Why can't we do that with NSArray?
MBTaskContainer
lets you add/read tasks from multiple threads in a safe way.
- Multiple readers and single writer/remover at a time.
MBTaskContainer
takes care of removal. You don't need to remove completed tasks.
Example Usage
// DataController.m
- (MBTaskContainer *)seriallyGetRepositoriesOrganizationsMembers {
MBTaskContainer *taskContainer = [MBTaskContainer new];
NSURLSessionTask *repositories = [self fetchDataWithRelativeURL:repositoriesURL completion:^(NSError *error) {
if (error == nil) {
NSURLSessionTask *organizations = nil;
organizations = [self fetchDataWithRelativeURL:organizationsURL completion:^(NSError *error) {
if (error == nil) {
NSURLSessionTask *members = nil;
members = [self fetchDataWithRelativeURL:membersURL completion:nil];
[taskContainer addTask:members];
}
}];
[taskContainer addTask:organizations];
}
}];
[taskContainer addTask:repositories];
return taskContainer;
}
// ViewController.m
...
self.serialTaskContainer = [self.dataController seriallyGetRepositoriesOrganizationsMembers];
NSArray *activeTasks = [self.serialTaskContainer getTasks];
...
// To cancel ongoing and potential new tasks
self.serialTaskContainer.state = MBTaskContainerStateCancelling;
...
Installation
MBTaskContainer is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod "MBTaskContainer"
Author
Mert Buran, buranmert@gmail.com
License
MBTaskContainer is available under the MIT license. See the LICENSE file for more info.