Julien7377
Julien7377

Reputation: 475

Determine when urlsession.shared and Json parsing are finished

I am downloading and then reading a json file. this json contains a list of files and their address on the server.

Everything works fine but I want to get the size of all files to download.

but I have some trouble to set up a completionblock that would indicate that everything is finished.

here is the code.

   jsonAnalysis {
        self.sum = self.sizeArray.reduce(0, +)
        print(self.sum)
    } here

func jsonAnalysis(completion:  @escaping () -> ()) {


    let urlString = "xxxxxxxxxxxxxxxxxxxxx"
    let url = URL(string: urlString)
    URLSession.shared.dataTask(with:url!) { (data, response, error) in
        if error != nil {
            print("error")

        } else {
            do {

                let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String: Any]
                self.i = -1
                guard let array = json?["Document"] as? [Any] else { return }

                for documents in array {

                    self.i = self.i + 1
                    guard let VersionDictionary = documents as? [String: Any] else { return }
                    guard let DocumentName = VersionDictionary["documentname"] as? String else { return }
                    guard let AddressServer = VersionDictionary["addressserver"] as? String else { return }

                    self.resultAddressServer.append(AddressServer)
                    self.addressServer = self.resultAddressServer[self.i]
                    self.resultDocumentName.append(DocumentName)
                    self.documentName = self.resultDocumentName[self.i]

                    let url1 = NSURL(string: AddressServer)
                    self.getDownloadSize(url: url1! as URL, completion: { (size, error) in
                        if error != nil {
                            print("An error occurred when retrieving the download size: \(String(describing: error?.localizedDescription))")
                        } else {
                            self.sizeArray.append(size)
                            print(DocumentName)
                            print("The download size is \(size).")

                        }
                    })

                }

            } catch {
                print("error")
            }

        }
            completion()

        }   .resume()

}

func getDownloadSize(url: URL, completion: @escaping (Int64, Error?) -> Void) {
    let timeoutInterval = 5.0
    var request = URLRequest(url: url,
                             cachePolicy: .reloadIgnoringLocalAndRemoteCacheData,
                             timeoutInterval: timeoutInterval)
    request.httpMethod = "HEAD"
    URLSession.shared.dataTask(with: request) { (data, response, error) in
        let contentLength = response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown
        completion(contentLength, error)
        }.resume()
}

I would like to get the sum of the array at the end when everything is done, right now print(self.sum) is running before and shows 0.

I am not familiar with the completion and I am sure I am doing everything wrong.

Upvotes: 0

Views: 100

Answers (1)

vadian
vadian

Reputation: 285280

You need DispatchGroup.

Before calling the inner asynchronous task enter, in the completion block of the inner asynchronous task leave the group.
Finally when the group notifies, call completion

let group = DispatchGroup()
for documents in array {
    ...

    let url1 = URL(string: AddressServer) // no NSURL !!!
    group.enter()
    self.getDownloadSize(url: url1!, completion: { (size, error) in
         if error != nil {
            print("An error occurred when retrieving the download size: \(String(describing: error?.localizedDescription))")
         } else {
            self.sizeArray.append(size)
            print(DocumentName)
            print("The download size is \(size).")
         }
         group.leave()
     })
}
group.notify(queue: DispatchQueue.main) {
    completion()
}

Upvotes: 2

Related Questions