Consider a scenario, I have a function "REFRESH", this function is called by different methods simultaneously, let's say the methods are "A", "B", "C". If method "A" calls "REFRESH TOKEN" firstly then methods "B" and "C" should wait until it finishes.
How can I attain this scenario? Appreciate your help!
let serialQueue = DispatchQueue(label: "serialQueue")
var myFlag = false
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.refresh(param: 1) // Method A
self.refresh(param: 2) // Method B
self.refresh(param: 3) // Method C
}
// Method REFRESH
func refresh(param: NSInteger) -> Void {
let absolutePath = "MY SAMPLE API"
var headers: [String: String] = Dictionary<String, String>();
headers["Content-Type"] = "application/json"
serialQueue.sync {
print("\nEntered ", param)
Alamofire.request(absolutePath, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: headers).responseString {
response in
switch response.result {
case .success:
print("SUCCESS")
break
case .failure(let error):
print(error)
}
}
Above code output:
Entered 1
Entered 2
Entered 3
SUCCESS
SUCCESS
SUCCESS
I need an output like this:
Entered 1
SUCCESS
Entered 2
SUCCESS
Entered 3
SUCCESS
What you need is something called resource locking. You can achieve this by using DispatchGroup
.
First you need to create a DispatchGroup
. Add a property in your controller:
let dispatchGroup = DispatchGroup()
Then modify your refresh(param:)
function as: (I've modified some of the coding patterns)
func refresh(param: NSInteger) -> Void {
// You lock your resource by entering to the dispatch group
dispatchGroup.enter()
let absolutePath = "MY SAMPLE API"
var headers = [String: String]()
headers["Content-Type"] = "application/json"
print("Entered \(param)")
Alamofire.request(absolutePath, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: headers).responseString { [weak self] (response) in
switch response.result {
case .success:
print("SUCCESS \(param)")
break
case .failure(let error):
print(error)
}
// You release the resource as soon as you get the response so that other processes may be able to use the resource
self?.dispatchGroup.leave()
}
// The lock continues by invoking the wait method
dispatchGroup.wait()
}
So, this will work as:
Method 1
& Method 2
are requesting to use the same resource. When Method 1
is executing, Method 2
will wait for Method 1 to finish. When Method 1
is finished, Method 2
will be given the opportunity to start it's execution.
So, basically which method first starts executing will finish and then the other will be started. Though it's not guaranteed which will start the execution first (As, you don't need dependency on each other). But it will depend on the sequence you invoke this method.