0

I've been trying multiple ways to run a function in a for in loop and when all have returned to run another function but for some reason it appears the final function is running before one or more of the others have returned a result.

This is my latest attempt: (both functions work it is just the order which is the issue)

var counter: Int = 0

    for owner in arrOwnerList {
        self.removeDevice(device: self.device, account: owner as! String) { (isSuccess) -> Void in
            print(isSuccess)
            if isSuccess {
                    }
            }
    }
    
    if self.arrOwnerList.count == self.counter {
        self.removeDeviceFromServer(device: self.device)
        self.sendEmail(to:"gordon@myemail.co.uk", subject:self.device+" has been removed", text:self.device+" has been removed from the server, please check the sim for bar and termination")
    }
}

func removeDevice(device: String, account: String, completion: @escaping (Bool) -> Void) {
    let dictHeader : [String:String] = ["username":username,"password":password]
    let dictArray = [device]
    self.counter += 1
    WebHelper.requestPUTAPIRemoveDevice(baseURL+"rootaccount/removedevices/"+account+"?server=MUIR", header: dictHeader, dictArray: dictArray, controllerView: self, success: { (response) in
        print(response)
        if response.count == 0 {
            self.Label1.alpha = 1
            print("response count == 0")
            DispatchQueue.main.async {
                GlobalConstant.showAlertMessage(withOkButtonAndTitle: GlobalConstant.AppName, andMessage: Messages.ServerError, on: self)
            }
        }
        else {
            
        }
    }) { (error) in
        DispatchQueue.main.async {
            GlobalConstant.showAlertMessage(withOkButtonAndTitle: GlobalConstant.AppName, andMessage: error?.localizedDescription ?? Messages.ServerError, on: self)
        }
    }
    let isSuccess = true
    self.Label1.alpha = 1
    completion(isSuccess)
}

    func removeDeviceFromServer(device: String) {
    let dictHeader : [String:String] = ["username":username,"password":password]
    
WebHelper.requestDELETEAPI(baseURL+"defaultdevice/"+device+"?server=MUIR", header: dictHeader, controllerView: self, success: { (response) in
        if response.count == 0 {
            DispatchQueue.main.async {
                GlobalConstant.showAlertMessage(withOkButtonAndTitle: GlobalConstant.AppName, andMessage: Messages.ServerError, on: self)
            }
        }
        else {
            if response.count != 0 {
                self.Label2.alpha = 1
                DispatchQueue.main.async {
                   self.Label2.alpha = 1
                }
            }
            else{
                DispatchQueue.main.async {
                    GlobalConstant.showAlertMessage(withOkButtonAndTitle: GlobalConstant.AppName, andMessage: Messages.NoDataFound, on: self)
                    
                }
            }
        }
    }) { (error) in
        DispatchQueue.main.async {
            GlobalConstant.showAlertMessage(withOkButtonAndTitle: GlobalConstant.AppName, andMessage: error?.localizedDescription ?? Messages.ServerError, on: self)
        }
    }
}
ruraldev
  • 187
  • 2
  • 13

1 Answers1

2

DispatchGroup will solve the problems. (https://developer.apple.com/documentation/dispatch/dispatchgroup)

let dispatchGroup = DispatchGroup()

for owner in arrOwnerList {
    dispatchGroup.enter()
    
    self.removeDevice(device: self.device, account: owner as! String) { (isSuccess) -> Void in
        
        defer {
            dispatchGroup.leave()
        }
        
        print(isSuccess)
        if isSuccess {
        }
    }
}

// This block execute when the loop is completed.
dispatchGroup.notify(queue: .main) { [weak self] in
    guard let self = self else { return }
    
    self.removeDeviceFromServer(device: self.device)
    self.sendEmail(to:"gordon@myemail.co.uk", subject:self.device+" has been removed", text:self.device+" has been removed from the server, please check the sim for bar and termination")
}
Raja Kishan
  • 16,767
  • 2
  • 26
  • 52
  • Worked perfectly, the only thing I had to do was add self. self.dispatchGroup.leave() Thanks Gordon – ruraldev Dec 12 '20 at 09:42
  • 1
    self is required because you have created dispatchGroup variable in the view controller class, not in a function. I suggest you keep create dispatchGroup variable within a function if you don't need to use it in the whole class. – Raja Kishan Dec 12 '20 at 10:02
  • Thanks, I've changed it, as they say every day's a school day! – ruraldev Dec 12 '20 at 10:07