确定urlsession.shared和Josn解析何时完成 [英] Determine when urlsession.shared and Josn parsing are finished

查看:110
本文介绍了确定urlsession.shared和Josn解析何时完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在下载,然后阅读json文件.该json包含文件列表及其在服务器上的地址.

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.

这是代码.

   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()
}

我想在完成所有操作后最后获取数组的总和,现在print(self.sum)正在运行并显示0.

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.

推荐答案

您需要DispatchGroup.

在调用内部异步任务enter之前,请在内部异步任务leave的完成块中使用该组.
最后,当组notifies时,呼叫completion

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()
}

这篇关于确定urlsession.shared和Josn解析何时完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆