swift - 为什么我的完成处理程序不能与我的 URLSession 一起工作?

标签 swift xcode urlsession

我的应用程序遇到了一个小问题。在我粘贴任何代码之前,让我提供一些上下文。我有一个带有一些动态单元格的 TableView。每个单元格都包含一个按钮。当我按下单元格内的按钮时,将调用一个函数来发出 URLSession 数据任务请求。我使用 Decodable 类来存储 JSON 结果,我想做的就是打印结果数组的计数。我遇到的问题;打印发生在返回结果之前。

为了解决这个问题,我尝试使用完成处理程序并在 DispatchGroup 中运行 URLSession,并且在 DispatchGroup 结束之前不打印。

我希望有人能快速浏览一下我的代码并指出我的错误。

这是我发出 URLSession 请求的函数:

func loadLocalPrice(selectedItemName: String, completion: @escaping (_ result: [PriceModel])-> Void) {

    var localPrice = [PriceModel]()

    let urlApi = "http://my.url.com/category/"+self.selectedCategory+"/"+selectedItemName

    guard let url = URL(string: urlApi) else {return completion(localPrice)}

    URLSession.shared.dataTask(with: url) { (data, response, error) in
        guard let data = data else {return}
        self.dispatchGroupLoadItems.enter()
        do {
            localPrice = try JSONDecoder().decode([PriceModel].self, from: data)
            print("The result inside the function is: \(localPrice.count)")
        } catch let JSONerror {
            print("error decoding JSON", JSONerror)
        }
        self.dispatchGroupLoadItems.leave()

        }.resume()
        return completion(localPrice)
}

下面是调用包含 URLSession 的上述函数的函数:

    func addToBasket(sender: UIButton, name: String?, category: String?) {
    var localPrice = [PriceModel]()

    DispatchQueue.main.async {
        self.loadLocalPrice(selectedItemName: name!) {
            (result: [PriceModel]) in
            print("got back inside the dispatchGroup: \(result.count)")

            localPrice = result
        }


        self.dispatchGroupLoadItems.notify(queue: .main) {
            print("Got back outside the dispatchGroup: \(localPrice.count)")
        }
    }
}

下面是我的控制台输出,因此您可以看到返回结果的顺序:

got back inside the dispatchGroup: 0
Got back outside the dispatchGroup: 0
The result inside the function is: 1

最佳答案

当您已经有了完成处理程序时,您就不需要 dispatchGroup 了。您的问题可以通过以下正确方式使用 completion 处理程序来解决,

func loadLocalPrice(selectedItemName: String, completion: @escaping (_ result: [PriceModel])-> Void) {

    var localPrice = [PriceModel]()

    let urlApi = "http://my.url.com/category/"+self.selectedCategory+"/"+selectedItemName

    guard let url = URL(string: urlApi) else { 
              completion(localPrice)
              return 
            }

    URLSession.shared.dataTask(with: url) { (data, response, error) in
        guard let data = data else {
               completion(localPrice)
               return
             }
        do {
            localPrice = try JSONDecoder().decode([PriceModel].self, from: data)
        } catch let JSONerror {
            print("error decoding JSON", JSONerror)
        }
        DispatchQueue.main.async {
          completion(localPrice)
        }
     }.resume() 
}

func addToBasket(sender: UIButton, name: String?, category: String?) {
    var localPrice = [PriceModel]()

    self.loadLocalPrice(selectedItemName: name!) {
        (result: [PriceModel]) in
        print("Count: \(result.count)")
        localPrice = result
    }
}

关于swift - 为什么我的完成处理程序不能与我的 URLSession 一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51380769/

相关文章:

ios - 如何将自定义类 UIButton 与同一类的另一个对象设置?

ios - URLSession 完成处理程序应用程序崩溃

ios - 为什么使用 Alamofire 请求失败?

ios - Quickblox + Swift 3.0 iOS SDK 错误 : No Application Found and QBConnectionZoneTypeProduction

Xcode swift 错误 App Transport Security 已阻止明文 HTTP

ios - 定义与 Swift 2.0 中的先前值冲突

swift - 简单的 URLSession 示例总是因错误而失败

ios - swift 3+,URLsession,在后台明显随机失败

编译 Swift 时的 Xcode 性能问题

xcode - 检索实体名称时崩溃?