[英]iOS swift how can I await an async task inside a function that needs a return value
我正在使用swift 3.0,並創建了一個返回整數數組的函數。 整數數組非常具體,它們是從數據庫中獲取的,因此HTTP調用是異步的。 這是一個功能,因為我在3個不同的控制器中使用了它,因此一次編寫它很有意義。 我的問題是異步代碼在底部的return語句后返回,因此它返回nil。 我在這里嘗試過該示例, 直到任務完成為止,但是它不能正常工作主要是因為我需要返回值。 這是我的代碼
func ColorSwitch(label: [UILabel]) -> [Int] {
for (index, _) in label.enumerated() {
label[index].isHidden = true
}
// I need the value of this variable in the return
// statement after the async is done
var placeArea_id = [Int]()
let urll:URL = URL(string:ConnectionString+"url")!
let sessionn = URLSession.shared
var requestt = URLRequest(url: urll)
requestt.httpMethod = "POST"
let group = DispatchGroup()
group.enter()
let parameterr = "http parameters"
requestt.httpBody = parameterr.data(using: String.Encoding.utf8)
let task = sessionn.dataTask(with:requestt, completionHandler: {(data, response, error) in
if error != nil {
print("check check error")
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:Any]
DispatchQueue.main.async {
if let Profiles = parsedData?["Results"] as? [AnyObject] {
if placeArea_id.count >= 0 {
placeArea_id = [Int]()
}
for Profiles in Profiles {
if let pictureS = Profiles["id"] as? Int {
placeArea_id.append(pictureS)
}
}
}
group.leave()
}
} catch let error as NSError {
print(error)
}
}
})
task.resume()
group.notify(queue: .main) {
// This is getting the value however can't return it here since it
// expects type Void
print(placeArea_id)
}
// this is nil
return placeArea_id
}
我已經檢查過了,這些值正在異步代碼中返回,現在只需要返回它,任何建議都將很棒。
您將為此使用閉包,或將函數更改為同步。
func ColorSwitch(label: [UILabel], completion:@escaping ([Int])->Void) {
completion([1,2,3,4]) // when you want to return
}
ColorSwitch(label: [UILabel()]) { (output) in
// output is the array of ints
print("output: \(output)")
}
這是一個關於閉包的不錯的博客http://goshdarnclosuresyntax.com/
您實際上無法讓函數從該函數內的異步操作返回值。 那會破壞異步的目的。 為了將數據傳遞回ColorSwitch(label:)
函數之外,您還需要使其接受一個閉包,閉包將在完成時被調用,該閉包接受一個[Int]
作為參數。 您的方法聲明將需要如下所示:
func ColorSwitch(label: [UILabel], completion: @escaping ([Int]) -> Void) -> Void {
for (index, _) in label.enumerated() {
label[index].isHidden = true
}
var placeArea_id = [Int]()
let urll:URL = URL(string:ConnectionString+"url")!
let sessionn = URLSession.shared
var requestt = URLRequest(url: urll)
requestt.httpMethod = "POST"
let group = DispatchGroup()
group.enter()
let parameterr = "http parameters"
requestt.httpBody = parameterr.data(using: String.Encoding.utf8)
let task = sessionn.dataTask(with:requestt, completionHandler: {(data, response, error) in
if error != nil {
print("check check error")
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:Any]
DispatchQueue.main.async {
if let Profiles = parsedData?["Results"] as? [AnyObject] {
if placeArea_id.count >= 0 {
placeArea_id = [Int]()
}
for Profiles in Profiles {
if let pictureS = Profiles["id"] as? Int {
placeArea_id.append(pictureS)
}
}
}
group.leave()
completion(placeArea_id) // This is effectively your "return"
}
} catch let error as NSError {
print(error)
}
}
})
task.resume()
}
稍后,您可以這樣稱呼它:
ColorSwitch(label: []) { (ids: [Int]) in
print(ids)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.