Search code examples
swiftdispatch-async

Waiting for two different REST/Network calls to complete


I am making a lot of calls using REST and decided to separate these connection calls into a separate object, to be called from my UI classes. Here is the function I am using, it will not wait for the requests to be complete. I am not sure what I am doing wrong and have tried using many examples off stack and the net, including:

Wait until swift for loop with asynchronous network requests finishes executing

Waiting until the task finishes

//let loader = from Oauth2/p2_OAuth2 pod to load JSON
func ConnectionHandler()
{

        let dg = DispatchGroup()

        switch self.RequestType
        {
        case aRequest:
            //if I make a single call here, works fine 
        case bRequest:
            //if I make a single call here, works fine 
        case abRequest:
            //when making requests for both type a and b, can’t get it to work
            dg.enter()

            loader.perform(request: self.userDataRequest)
            { response in
                do
                {
                    let json = try response.responseJSON()
                    self.structWrapper.aArray = self.loadAArray(dict: json)
                }
                catch let error {
                    self.didCancelOrFail(error)
                }
            }
            self.dexRequestType = DexRequestTypesEnum.glucoseValues
            //ignore last line.  should be removed.
            loader.perform(request: self.userDataRequest)
            { response in
                do
                {
                    let json = try response.responseJSON()
                    self.structWrapper.bArray = self.loadBArray(dict: json)                }
                catch let error {
                    self.didCancelOrFail(error)
                }
            }
            dg.leave()
            dg.notify(queue: .main) 
            {
                //will print, but requests are not complete, arrays are empty, even though breakpoints hit in loading them.
              for x in self.structWrapper.aArray                  
               {
                 print(x.displayTime + ":" + x.units)
               }
               for y in self.structWrapper.bArray
               {
                print(y.displayTime + ":" + String(y.someNumber) 
               }
                print(“tasks complete”)
             }

        }

    }

Solution

  • you have to use

    dg.enter() before call Task

    dg.leave() after task finished

    Like that:

    func ConnectionHandler()
    {
    
        let dg = DispatchGroup()
    
        switch self.RequestType
        {
        case aRequest:
            //if I make a single call here, works fine 
        case bRequest:
            //if I make a single call here, works fine 
        case abRequest:
            //when making requests for both type a and b, can’t get it to work
            dg.enter()
    
            loader.perform(request: self.userDataRequest)
            { response in
                do
                {
                    let json = try response.responseJSON()
                    self.structWrapper.aArray = self.loadAArray(dict: json)
                }
                catch let error {
                    self.didCancelOrFail(error)
                }
    
               dg.leave()
            }
            self.dexRequestType = DexRequestTypesEnum.glucoseValues
    
            dg.enter()
    
            loader.perform(request: self.userDataRequest)
            { response in
                do
                {
                    let json = try response.responseJSON()
                    self.structWrapper.bArray = self.loadBArray(dict: json)                }
                catch let error {
                    self.didCancelOrFail(error)
                }
    
              dg.leave()
            }
    
            group.notify(queue: .main) 
            {
                //will print, but requests are not complete, arrays are empty, even though breakpoints hit in loading them.
              for x in self.structWrapper.aArray                  
               {
                 print(x.displayTime + ":" + x.units)
               }
               for y in self.structWrapper.bArray
               {
                print(y.displayTime + ":" + String(y.someNumber) 
               }
                print(“tasks complete”)
             }
    
        }
    
    }