【问题标题】:Determine when urlsession.shared and Json parsing are finished确定 urlsession.shared 和 Json 解析何时完成
【发布时间】:2019-02-11 19:42:41
【问题描述】:

我正在下载然后读取一个 json 文件。此 json 包含文件列表及其在服务器上的地址。

一切正常,但我想获取要下载的所有文件的大小。

但是我在设置一个表明一切都已完成的完成块时遇到了一些麻烦。

这里是代码。

   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。

我不熟悉完成,我确定我做错了。

【问题讨论】:

    标签: ios json swift urlsession


    【解决方案1】:

    您需要DispatchGroup

    在调用内部异步任务enter之前,在内部异步任务leave的完成块中组。
    最后当群notifies,拨打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()
    }
    

    【讨论】:

    • 它工作得很好,最后给了我预期的总尺寸谢谢!!
    • 您总是可以将异步调用包装到另一个中,然后在触发时使用一个回调,在完成时使用另一个回调。类似于 UIAnimation 需要两个块。见here
    猜你喜欢
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    相关资源
    最近更新 更多