如何从 URLSession 中获取值

How to get value out of URLSession

我一直回到同样的问题。对于我应用程序的其他部分,我在解析 API 后直接使用了 coredata 并且工作正常。但是,现在我想解析通过 API 接收到的 JSON 并只获取一个值来计算其他值,然后将其放入 Coredata.

一切正常,我已将 URLSessions 代码设置如下:

func fetchData(brand: String, completion: @escaping ((Double) -> Void)) {
    let urlString = "\(quoteUrl)\(brand)"
    if let url = URL(string: urlString) {
        var session = URLRequest(url: url)
        session.addValue("application/json", forHTTPHeaderField: "Accept")
        session.addValue("Bearer \(key)", forHTTPHeaderField: "Authorization")
        let task = URLSession.shared.dataTask(with: session) { (data, response, error) in
            if error != nil {
                print(error!)
                return
            }
            if let safeData = data  {
                let decoder = JSONDecoder()
                do {
                let decodedData = try decoder.decode(DataModel.self, from: safeData)
                let bid = decodedData.quotes.quote.bid
                let ask = decodedData.quotes.quote.ask
                let itemPrice: Double = (bid + ask)/2
                completion(itemPrice)
                } catch {
                        print(error)
                }
            }
        }
        task.resume()
        } 
    }

我正在使用 completionHandler 检索我在另一个文件中使用的部分,如下所示:

func getGainLossNumber(brand: String, quantity: Int, price: Double) -> Double {
    var finalPrice = 0.0
    APImodel.fetchData(brand: brand) { returnedDouble in
    let currentPrice = returnedDouble

    if quantity < 0 {
    let orderQuantity = quantity * -1
    finalPrice = price + (currentPrice*(Double(orderQuantity))*100)
    } else {
    finalPrice = price - (currentPrice*(Double(quantity))*100)
    }
    
    }
    return finalPrice
}

finalPrice 最终 returns 0.0。如果我在闭包中打印 currentPrice,我会得到正确的结果。由于我遇到的问题,我使用完成处理程序从 API 中检索一个数字,但它仍然没有做我想做的事情。第二个函数应该 return 使用我从完成处理程序检索到的 API 中获得的值计算的值。

我只是不知道该怎么做。

问题是您在闭包内计算 finalPrice,这是 异步。但是,您的 getGainLossNumber 方法是 同步 ,因此它实际上 returns 在您的闭包完成计算 finalPrice 之前。重组您的代码,以便 getGainLossNumber 将闭包作为参数,并在计算 finalPrice 后调用它。类似于:

func getGainLossNumber(brand: String, quantity: Int, price: Double, _ completion: @escaping (Double) -> Void) {
    APImodel.fetchData(brand: brand) { returnedDouble in
        let currentPrice = returnedDouble

        let finalPrice: Double
        if quantity < 0 {
            let orderQuantity = quantity * -1
            finalPrice = price + (currentPrice*(Double(orderQuantity))*100)
        }
        else {
            finalPrice = price - (currentPrice*(Double(quantity))*100)
        }
        
        completion(finalPrice)
    }
}

另请注意,finalPrice 不需要是 var,因为它只会被赋值一次。

编辑

用法:

getGainLossNumber(brand: "brand", quantity: 1, price: 120, { finalPrice in
    // You can access/use finalPrice in here.
}