Swift 从另一个文件调用完成处理程序失败
Swift calling completion handler in from another file fails
我正在从一个调用到另一个调用带有 completio=n 处理程序的函数 class
被称为class:
class PVClass
{
var avgMonthlyAcKw:Double = 0.0
var jsonString:String!
func estimateMonthlyACkW (areaSqFt:Float, completion: @escaping(Double) -> () ){
var capacityStr:String = ""
let estimatedCapacity = Float(areaSqFt/66.0)
capacityStr = String(format: "%.2f", estimatedCapacity)
// Build some Url string
var urlString:String = "https://developer.nrel.gov/"
urlString.append("&system_capacity=")
urlString.append(capacityStr)
let pvURL = URL(string: urlString)
let dataTask = URLSession.shared.dataTask(with: pvURL!) { data, response, error in
do {
let _ = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
self.jsonString = String(data: data!, encoding: .utf8)!
print("JSON String:\(String(describing: self.jsonString))")
if self.jsonString != nil {
let decoder = JSONDecoder()
let jsonData = try decoder.decode(PVClass.Top.self, from: data!)
// do some parsing here
var totalAcKw: Double = 0.0
let cnt2: Int = (jsonData.Outputs?.ACMonthly.count)!
for i in 0..<(cnt2-1) {
totalAcKw = totalAcKw + (jsonData.Outputs?.ACMonthly[i])!
}
self.avgMonthlyAcKw = Double(totalAcKw)/Double(cnt2)
// prints value
print("updated estimate: ", self.avgMonthlyAcKw)
}
} catch {
print("error: \(error.localizedDescription)")
}
}
dataTask.resume()
completion(self.avgMonthlyAcKw)
}
呼叫 Class:
func estimate() {
var estimatedSolarkWh:Double = 0.0
let aPVClass = PVClass()
aPVClass.estimateMonthlyACkW(areaSqFt: 100.0, completion: { (monthlyAckW) -> Void in
estimatedSolarkWh = monthlyAckW
self.view.setNeedsDisplay()
})
return
}
}
当我调用函数 estimate() 时,另一个 PVClass 中的 estimateMonthlyACkW 函数被执行,但它 returns 在调用 estimate() 函数被执行之后。因此,即使在被调用的函数中执行了 URLsession,json 被解析,并且值被正确打印 - 值永远不会被传输到完成处理程序并且该值永远不会返回调用 class。我该如何解决这个问题?
您需要在打印语句之后移动 completion(self.avgMonthlyAcKw)
,如下所示:
// prints value
print("updated estimate: ", self.avgMonthlyAcKw)
completion(self.avgMonthlyAcKw)
希望对您有所帮助:)
我正在从一个调用到另一个调用带有 completio=n 处理程序的函数 class
被称为class:
class PVClass
{
var avgMonthlyAcKw:Double = 0.0
var jsonString:String!
func estimateMonthlyACkW (areaSqFt:Float, completion: @escaping(Double) -> () ){
var capacityStr:String = ""
let estimatedCapacity = Float(areaSqFt/66.0)
capacityStr = String(format: "%.2f", estimatedCapacity)
// Build some Url string
var urlString:String = "https://developer.nrel.gov/"
urlString.append("&system_capacity=")
urlString.append(capacityStr)
let pvURL = URL(string: urlString)
let dataTask = URLSession.shared.dataTask(with: pvURL!) { data, response, error in
do {
let _ = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
self.jsonString = String(data: data!, encoding: .utf8)!
print("JSON String:\(String(describing: self.jsonString))")
if self.jsonString != nil {
let decoder = JSONDecoder()
let jsonData = try decoder.decode(PVClass.Top.self, from: data!)
// do some parsing here
var totalAcKw: Double = 0.0
let cnt2: Int = (jsonData.Outputs?.ACMonthly.count)!
for i in 0..<(cnt2-1) {
totalAcKw = totalAcKw + (jsonData.Outputs?.ACMonthly[i])!
}
self.avgMonthlyAcKw = Double(totalAcKw)/Double(cnt2)
// prints value
print("updated estimate: ", self.avgMonthlyAcKw)
}
} catch {
print("error: \(error.localizedDescription)")
}
}
dataTask.resume()
completion(self.avgMonthlyAcKw)
}
呼叫 Class:
func estimate() {
var estimatedSolarkWh:Double = 0.0
let aPVClass = PVClass()
aPVClass.estimateMonthlyACkW(areaSqFt: 100.0, completion: { (monthlyAckW) -> Void in
estimatedSolarkWh = monthlyAckW
self.view.setNeedsDisplay()
})
return
}
}
当我调用函数 estimate() 时,另一个 PVClass 中的 estimateMonthlyACkW 函数被执行,但它 returns 在调用 estimate() 函数被执行之后。因此,即使在被调用的函数中执行了 URLsession,json 被解析,并且值被正确打印 - 值永远不会被传输到完成处理程序并且该值永远不会返回调用 class。我该如何解决这个问题?
您需要在打印语句之后移动 completion(self.avgMonthlyAcKw)
,如下所示:
// prints value
print("updated estimate: ", self.avgMonthlyAcKw)
completion(self.avgMonthlyAcKw)
希望对您有所帮助:)