如何将变量值传递到URLSession异步外部-Swift 3 [英] how to pass variable value to outside of URLSession async - swift 3

查看:72
本文介绍了如何将变量值传递到URLSession异步外部-Swift 3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有此代码:

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 has been defined previously. I did anything to set returnDetail value to getDetail!.base64Decoded() but it only works inside let task = ...

如何将其传递给外部范围?

How can I pass it to the outer scope?

推荐答案

您有几种方法可以解决从异步函数内部返回值的问题.其中之一是将异步网络调用包装在一个函数中,并使其返回一个completionHandler.

You have several methods to tackle the issue of returning a value from inside an asynchronous function. One of them is to wrap the asynchronous network call inside a function and make it return a completionHandler.

一些一般性建议:除非您100%确定可选值不会为nil,否则请勿使用强制展开.对于网络请求,即使没有错误,data也可以为零,因此切勿强行解包data,对if letguard let使用安全的解包.解析JSON值时,请勿在Swift中使用.mutableContainers,因为它没有效果.解析的JSON对象的可变性是通过使用letvar关键字来声明保存它的变量来确定的.也不要使用NSDictionary,使用其本机Swift副本,即Dictionary([String:Any]是类型Dictionary<String,Any>的简写).

Some general advice: don't use force unwrapping unless you are 100% sure that your optional value won't be nil. With network requests, the data can be nil even if there's no error, so never force unwrap data, use safe unwrapping with if let or guard let. Don't use .mutableContainers in Swift when parsing a JSON value, since it has no effect. The mutability of the parsed JSON object is decided by using the let or var keyword to declare the variable holding it. Also don't use NSDictionary, use its native Swift counterpart, Dictionary ([String:Any] is a shorthand for the type 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()
}

然后您可以通过以下方式调用此功能

Then you can call this function by

getDetail(withRequest: request, withCompletion: { detail, error in
    if error != nil {
        //handle error
    } else if detail = detail {
        //You can use detail here
    }
})

这篇关于如何将变量值传递到URLSession异步外部-Swift 3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆