我有这个代码:
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 = ...
returnDetail
getDetail!.base64Decoded()
let task = ...
如何将其传递给外部范围?
您有几种方法可以解决从异步函数内部返回值的问题。其中之一是将异步网络调用包装在一个函数中,并使其返回一个completionHandler。
一些一般性建议:除非您100%确信不会将可选值设为,否则请勿使用强制展开nil。对于网络请求,data即使没有错误,也可以为零,因此切勿强行展开data,请使用if let或安全地展开guard let。.mutableContainers解析JSON值时请勿在Swift中使用,因为它无效。解析的JSON对象的可变性是通过使用letor var关键字来声明保存它的变量来确定的。也不要使用NSDictionary,请使用本机的Swift对应字典Dictionary([String:Any]是type的简写Dictionary<String,Any>)。
nil
data
if let
guard let
.mutableContainers
let
var
NSDictionary
[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 } })