It is a typical design pattern to use a Singleton to represent an "API Manager" object like this:-
class APIManager {
let ENDPOINT_URL = "http://remote-server-fqdn.com"
var storage : Storage!
var currentlyLoggedIn = false
class var sharedInstance: APIManager {
struct Static {
//---to contain the one and only instance of this class---
static var instance: APIManager!
//---a token to ensure that the class is only instantiated once---
static var token: dispatch_once_t = 0
}
//---executes a block object once and only once for the lifetime of an application---
dispatch_once(&Static.token) {
//---creates an instance of this class---
Static.instance = APIManager()
Static.instance.storage = Storage.sharedInstance
}
//---returns the instance of this class---
return Static.instance
}
This ensures that we have an APIManager
object, with a consistent token, that we can use at different parts of our ViewController or Model methods. Not much of a problem and easily understood.
THE QUESTION
However, the question is --- is it appropriate to also include actual API server calls (or any kind of asynchronous execution) which are already async by nature if I am using libraries such as Alamofire or AFNetworking as methods into my APIManager
class?
Will the fact that these (async) methods are nested inside my Singleton class cause any unintended performance issue or unintended side effects?
I understand that the async
server API calls or a dispatch_async
method will make use of GCD and concurrency is still achieved.
As an additional question: is this concurrency achieved by the Singleton's async method calls concurrent parallel OR concurrent but not parallel?
For instance, like this:-
class APIManager {
// .... same block of code as above for declaring dispatch_once above.
// additional code which are API server calls (and async by nature) here
func loginRequest(username : String, password : String, completion: (loginSuccess : Bool) -> Void) {
// Alamofire.request ...
}
func getRequest(...) {
// Alamofire.request ...
}
func postRequest(...) {
// Alamofire.request ...
}
func testAsync() {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
println("just do something asynchronously")
}
}
}