How to run synchronously two functions with asynchronous operations in iOS using Swift

offers this scenario

asynchronous network operation method

func asyncMethodA() -> String? { result : String? Alamofire.manager.request(.POST, "https://www.apiweb.com/apimethod", parameters: parameters, encoding:.JSON) .response { (request, response, rawdata, error) in if (response?.statusCode == 200) { //DO SOME HEAVY LIFTING } } return result //string } 

another method with asynchronous network operations

 func asyncMethodB() -> String? { result : String? Alamofire.manager.request(.POST, "https://www.yetanotherapiweb.com/apimethod", parameters: parameters, encoding:.JSON) .response { (request, response, rawdata, error) in if (response?.statusCode == 200) { //DO SOME HEAVY LIFTING } } return result //string } 

the method in which I will call these methods A and B, perform some operations

 func displayResult { 1) let a = asyncMethodA() 2) let b = asyncMethodB() 3) println(a + b) //some chaotic stuff might happen :( } 

so the question is how could I make (2) wait for (1) to complete, and (3) wait (2), etc. (that 1,2 and 3 are started synchronously)?

(I know that one answer is to chain asyncMethodA and displayResult in asyncMethodB, but want to know if there is any other method)

Thank you!

+6
source share
3 answers
 func anAsyncMethod(resultHandler: (result: AnyObject) -> Void) { ... } func anotherAsyncMethod(resultHandler: (result: AnyObject) -> Void) { ... } let operationQueue = NSOperationQueue() func performWithCompletionHandler(completion: (AnyObject?, AnyObject?) -> Void) { var resultOfOperation1: AnyObject? var resultOfOperation2: AnyObject? let operation1 = NSBlockOperation { let dispatchGroup = dispatch_group_create() dispatch_group_enter(dispatchGroup) self.anAsyncMethod { result in resultOfOperation1 = result dispatch_group_leave(dispatchGroup) } // wait until anAsyncMethod is completed dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER) } let operation2 = NSBlockOperation { let dispatchGroup = dispatch_group_create() dispatch_group_enter(dispatchGroup) self.anotherAsyncMethod { result in resultOfOperation2 = result dispatch_group_leave(dispatchGroup) } // wait until anotherAsyncMethod is completed dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER) } let completionOperation = NSBlockOperation { // send all results to completion callback completion(resultOfOperation1, resultOfOperation2) } // configuring interoperation dependencies operation2.addDependency(operation1) completionOperation.addDependency(operation2) operationQueue.addOperations([operation1, operation2, completionOperation], waitUntilFinished: false) } 
+17
source

Using the below, you can run both asynchronization methods at the same time and do the hard work after the latter finishes.

 var methodAFinished = false var methodBFinished = false func asyncMethodA() -> String? { Alamofire.manager.request(.POST, "https://www.apiweb.com/apimethod", parameters: parameters, encoding:.JSON) .response { (request, response, rawdata, error) in if (response?.statusCode == 200) { methodAFinished = true doStuff() } } return result //string } 

The guts of asyncMethodB will be methodBFinished = true; doStuff() methodBFinished = true; doStuff()

 func doStuff() { if methodAFinished && methodBFinished { // do crazy stuff } } 
+1
source

Thanks to Yimin for the code above. I updated it to the latest Swift syntax, so just a post would be helpful:

 func anAsyncMethod(resultHandler: (_ result: AnyObject) -> Void) { ... } func anotherAsyncMethod(resultHandler: (_ result: AnyObject) -> Void) { ... } func performWithCompletionHandler(completion: @escaping (AnyObject?, AnyObject?) -> Void) { let operationQueue = OperationQueue() var resultOfOperation1: AnyObject? var resultOfOperation2: AnyObject? let operation1 = BlockOperation { let dispatchGroup = DispatchGroup() dispatchGroup.enter() self.anAsyncMethod { result in resultOfOperation1 = result dispatchGroup.leave() } // wait until anAsyncMethod is completed dispatchGroup.wait(timeout: DispatchTime.distantFuture) } let operation2 = BlockOperation { let dispatchGroup = DispatchGroup() dispatchGroup.enter() self.anotherAsyncMethod { result in resultOfOperation2 = result dispatchGroup.leave() } // wait until anotherAsyncMethod is completed dispatchGroup.wait(timeout: DispatchTime.distantFuture) } let completionOperation = BlockOperation { // send all results to completion callback completion(resultOfOperation1, resultOfOperation2) } // configuring interoperation dependencies operation2.addDependency(operation1) completionOperation.addDependency(operation2) operationQueue.addOperations([operation1, operation2, completionOperation], waitUntilFinished: false) } 
0
source

Source: https://habr.com/ru/post/978807/


All Articles