我有这段代码:
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil {
print(error!)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let getDetail = parseJSON["detail"] as? String
returnDetail = getDetail!.base64Decoded()
} // parse json end
} // do end
catch {
print(error)
}
} // let task end
之前已经定义了 returnDetail
。我做了一些事情来将returnDetail
值设置为getDetail!.base64Decoded()
,但它仅适用于let task = ...
如何将其传递到外部范围?
答案 0 :(得分:3)
您有几种方法可以解决从异步函数内部返回值的问题。其中之一是将异步网络调用包装在函数中,并使其返回completionHandler。
一些一般性建议:除非您100%确定您的可选值不是nil
,否则请勿使用强制解包。对于网络请求,即使没有错误,data
也可以为零,因此请勿强制解包data
,请使用if let
或guard let
进行安全解包。解析JSON值时不要在Swift中使用.mutableContainers
,因为它没有效果。解析的JSON对象的可变性通过使用let
或var
关键字来声明保存它的变量来确定。也不要使用NSDictionary
,使用其原生的Swift对应词,Dictionary([String:Any]
是Dictionary<String,Any>
类型的简写)。
func getDetail(withRequest request: URLRequest, withCompletion completion: @escaping (String?, Error?) -> Void) {
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil {
completion(nil, error)
return
}
else if let data = data {
do {
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String:Any] else {completion(nil, nil);return}
guard let details = json["detail"] as? String else {completion(nil, nil);return}
completion(details, nil)
}
catch {
completion(nil, error)
}
}
}
task.resume()
}
然后你可以通过
调用这个函数getDetail(withRequest: request, withCompletion: { detail, error in
if error != nil {
//handle error
} else if detail = detail {
//You can use detail here
}
})
答案 1 :(得分:0)
我建议使用完成处理程序。
func foo(withCompletion completion: (String?, Error?) -> Void) {
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil {
completion(nil, error)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let details = parseJSON["detail"] as? String
completion(details, nil)
} // parse json end
} // do end
catch {
completion(nil, error)
}
} // let task end
}
答案 2 :(得分:0)
我认为,当getDetail有数据时,你使用Swift的CallBack(Clourse)来返回数据。