All Operation is completed or not
In iOS basically we perform the background thread operation using GCD & OPeration, OPerationQueue.
In GCD there is DispatchGroup for handling the work is completed or not (different DispatchWorkItem ). In Operation, there is no kind of facility for this we have to create KVO
to manage all things. here we have taken the example of 2 Operation each Operation is downloading the image.
Please follow these steps:
1: First Create Operation class that will download the image.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
class AsyncTask:Operation{ var imageURL:URL init(url:URL) { self.imageURL = url } override func main() { //4 if isCancelled { return } //5 guard let imageData = try? Data(contentsOf: imageURL) else { return } //6 if isCancelled { return } if !imageData.isEmpty{ print("downloaded") } } } |
2: Take a controller class and Declare OperationQueue.
1 2 3 4 5 6 7 8 |
class ViewController: UIViewController { let queue = OperationQueue() var observation : NSKeyValueObservation? } |
Notes: It will add all the operations in the queue.
3: Write the function for operation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
func callAPI_OPERATION(){ if let urlDAta1 = URL(string: "https://picsum.photos/id/579/200/300"){ let op1 = AsyncTask(url:urlDAta1) op1.queuePriority = .high queue.addOperation(op1) op1.completionBlock = { print("op1") } } if let urlDAta2 = URL(string: "https://picsum.photos/id/579/200/300"){ let op1 = AsyncTask(url:urlDAta2) queue.addOperation(op1) op1.completionBlock = { print("op2") } } } |
Note: here op1 & op2 is separate completion of the operation.
4: Now Observe all the operation is completed or not.
Write this code in your class.
1 2 3 4 5 6 7 |
observation = queue.observe(\.operationCount, options: [.new]) { [unowned self] (queue, change) in if change.newValue! == 0 { // This will call when All Opeartion complete. self.observation = nil } } |
Now: Here we have implemented KVO to check whether the Queue contains operation or not.
Complete Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
class ViewController: UIViewController { let queue = OperationQueue() var observation : NSKeyValueObservation? override func viewDidLoad() { super.viewDidLoad() queue.qualityOfService = .userInitiated observation = queue.observe(\.operationCount, options: [.new]) { [unowned self] (queue, change) in if change.newValue! == 0 { self.observation = nil } } self.callAPI_OPERATION() } func callAPI_OPERATION(){ if let urlDAta1 = URL(string: "https://picsum.photos/id/579/200/300"){ let op1 = AsyncTask(url:urlDAta1) op1.queuePriority = .high queue.addOperation(op1) op1.completionBlock = { print("op1") } } if let urlDAta2 = URL(string: "https://picsum.photos/id/579/200/300"){ let op1 = AsyncTask(url:urlDAta2) queue.addOperation(op1) op1.completionBlock = { print("op2") } } } } class AsyncTask:Operation{ var imageURL:URL init(url:URL) { self.imageURL = url } override func main() { //4 if isCancelled { return } //5 guard let imageData = try? Data(contentsOf: imageURL) else { return } //6 if isCancelled { return } if !imageData.isEmpty{ print("downloaded") } } } |
Reference: