Json Swift-从完成处理程序中获取数据-解码数据

Json Swift-从完成处理程序中获取数据-解码数据,json,swift,urlsession,Json,Swift,Urlsession,我正在对一个邮政编码信息站点进行api调用,并编写了一个函数来获取数据,然后用JSONDecoder对其进行解析……问题是,当我调用该函数时,数据被捕获在完成处理程序中。在不必使用委托的情况下,是否有方法从完成处理程序中提取值以在类中的其他位置使用 struct ZipCodeDataManager { func getZipData(zipCode: String, userCompletionHandler: @escaping (ZipCodeCityData?, Error?)

我正在对一个邮政编码信息站点进行api调用,并编写了一个函数来获取数据,然后用JSONDecoder对其进行解析……问题是,当我调用该函数时,数据被捕获在完成处理程序中。在不必使用委托的情况下,是否有方法从完成处理程序中提取值以在类中的其他位置使用

struct ZipCodeDataManager {
    func getZipData(zipCode: String, userCompletionHandler: @escaping (ZipCodeCityData?, Error?) -> Void) {
        let urlString = "https://www.zipcodeapi.com/rest/apiKeyHere/info.json/\(zipCode)/degrees"
        
        if let url = URL(string: urlString) {
            URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
                if let data = data {
                    let jsonDecoder = JSONDecoder()
                    do {
                        let parsedJSON = try jsonDecoder.decode(ZipCodeCityData.self, from: data)
                        let city = parsedJSON.city
                        let state = parsedJSON.state
                        let lat = parsedJSON.lat
                        let lng = parsedJSON.lng
                        
                        let finalData = ZipCodeCityData(city: city, state: state, lat: lat, lng: lng)
                        
                        userCompletionHandler(finalData, nil)
                        
                    } catch {
                        print(error)
                        userCompletionHandler(nil,error)
                    }
                }
            })
            .resume()
        }
    }
}

struct ZipCodeCityData: Decodable {
    let city: String
    let state: String
    let lat: Double
    let lng: Double
}

let zipCodeManager = ZipCodeDataManager()


//these values aren't updating when the function is called
var city = ""
var state = ""
var lat = 0.0
var lng = 0.0

func getDataFromZip() {
    let zip = zipCodeManager.getZipData(zipCode: "91203") { (data, error) in
        if error != nil {
            print(error)
        }

        // trying to update the values here
        city = data!.city
        state = data!.state
        lat = data!.lat
        lng = data!.lng
    }
}

可以尝试使用公共变量而不是完成处理程序。我还在我的一个项目中使用了这种方法:

    //Posts image data in Constants class
func downloadImageFrom(urlString: String){
    let url = URL(string: urlString)!
    
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    
    var data: Data?
    
    URLSession.shared.dataTask(with: request) { (d, r, e) in
        guard let dat = d else {
            print("No Data")
            return
        }
                
        guard r == r else {
            print("No Response")
            return
        }
                
        if let err = e {
            print("ERROR: \(err)")
        }
                
        data = dat
        Constants.imageData = data
            
            
        NotificationCenter.default.post(name: Notification.Name(rawValue: "NewImageData"), object: self)
            
            
    }.resume()
    

您是否在
parsedJSON
对象中获取值?调试或打印I如何判断值未更新?您在哪里调用
getDataFromZip
from?你在哪里检查?你在
getDataFromZip()
中使用完成的结果,所以我不知道你为什么说“数据被捕获在完成处理程序中”。你在哪里调用
getDataFromZip()
?请注意,如果发生错误,代码将可靠地崩溃。在完成处理程序中添加
else
子句,或在
print(error)
之后添加return语句。顺便说一下:还打印潜在的
URLSession
错误。结构下的代码声明了方法
getDataFromZip()
,但没有调用它。