Swift 为什么可以';是否更改此会话中的实例变量。dataTask()?
我试图直接将从URLsession接收到的数据更新到实例变量中。在playgroud中尝试了下面的代码,直到Swift 为什么可以';是否更改此会话中的实例变量。dataTask()?,swift,Swift,我试图直接将从URLsession接收到的数据更新到实例变量中。在playgroud中尝试了下面的代码,直到self.cityName=weatherdecoded.name代码似乎工作正常,但是作为实例变量的self.cityName没有更新。结果是nils。希望了解原因,我犯了什么错误。谢谢 import UIKit class WeatherManager { var cityName: String? var conditionID: Int? var temp:
self.cityName=weatherdecoded.name
代码似乎工作正常,但是作为实例变量的self.cityName
没有更新。结果是nil
s。希望了解原因,我犯了什么错误。谢谢
import UIKit
class WeatherManager {
var cityName: String?
var conditionID: Int?
var temp: Double?
func fetchData(cityName: String) {
let session = URLSession(configuration: .default)
let urlStr = "https://api.openweathermap.org/data/2.5/weather?units=metric&appid=8da179fa1c83749056ec6a5385cabb04&q=" + cityName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
print(urlStr)
let url = URL(string: urlStr)!
let weatherDataSession = session.dataTask(with: url, completionHandler: getdata(data:response:error:))
weatherDataSession.resume()
}
func getdata(data: Data?, response: URLResponse?, error: Error?) {
if error != nil {
print(error!)
return
}
if let safedata = data {
let decoder = JSONDecoder()
do {
let weatherdecoded = try decoder.decode(Weatherdata.self, from: safedata)
self.cityName = weatherdecoded.name
self.conditionID = weatherdecoded.weather[0].id
self.temp = weatherdecoded.main.temp
} catch {
print(error)
}
}
}
}
struct Weatherdata: Decodable {
let weather : [Weather]
let main: Main
let name: String
}
struct Weather: Decodable {
let id: Int
let description: String
}
struct Main: Decodable {
let temp: Double
}
let weathermanager = WeatherManager()
weathermanager.fetchData(cityName: "beijing")
print(weathermanager.cityName)
print(weathermanager.conditionID)
print(weathermanager.temp)
原因很简单,因为您正在请求实际完成之前打印这些值。您必须使用完成处理程序:
class WeatherManager {
func fetchObject<T: Decodable>(urlPath: String, onCompletion: @escaping (Result<T, Error>) -> Void) {
let session = URLSession(configuration: .default)
let url = URL(string: urlPath)!
let task = session.dataTask(with: url) { data, _, error in
if let error = error {
onCompletion(.failure(error))
return
}
let decoder = JSONDecoder()
do {
let decoded = try decoder.decode(T.self, from: data ?? Data())
onCompletion(.success(decoded))
} catch {
onCompletion(.failure(error))
}
}
task.resume()
}
func fetchWeather(cityName: String, onCompletion: @escaping (Result<Weatherdata, Error>) -> Void) {
let urlPath = "https://api.openweathermap.org/data/2.5/weather?units=metric&appid=8da179fa1c83749056ec6a5385cabb04&q=" + cityName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
fetchObject(urlPath: urlPath, onCompletion: onCompletion)
}
}
struct Weatherdata: Decodable {
let weather : [Weather]
let main: Main
let name: String
}
struct Weather: Decodable {
let id: Int
let description: String
}
struct Main: Decodable {
let temp: Double
}
let weathermanager = WeatherManager()
weathermanager.fetchWeather(cityName: "beijing") { result in
switch result {
case .success(let weatherData):
print(weatherData.name)
print(weatherData.weather[0].id)
print(weatherData.main.temp)
case .failure(let error):
print(error)
}
}
类天气管理器{
func fetchObject(urlPath:String,onCompletion:@escaping(Result)->Void){
let session=URLSession(配置:。默认值)
让url=url(字符串:urlPath)!
让task=session.dataTask(with:url){data,\中出现错误
如果let error=error{
完成(.failure(error))
返回
}
let decoder=JSONDecoder()
做{
let decoded=尝试decoder.decode(T.self,from:data??data())
完成(.success(已解码))
}抓住{
完成(.failure(error))
}
}
task.resume()
}
func fetchWeather(cityName:String,onCompletion:@escaping(Result)->Void){
让urlPath=”https://api.openweathermap.org/data/2.5/weather?units=metric&appid=8da179fa1c83749056ec6a5385cabb04&q=“+cityName.addingPercentEncoding(使用允许的字符:.urlQueryLowed)!
fetchObject(urlPath:urlPath,onCompletion:onCompletion)
}
}
结构Weatherdata:可解码{
让天气:[天气]
让main:main
let name:String
}
结构天气:可解码{
让id:Int
let description:字符串
}
主结构:可解码{
温度:双倍
}
让weathermanager=weathermanager()
weathermanager.fetchWeather(城市名称:“北京”){结果
切换结果{
成功案例(让weatherData):
打印(weatherData.name)
打印(weatherData.weather[0].id)
打印(天气数据主温度)
案例。失败(let错误):
打印(错误)
}
}
URLSession.dataTask
是异步的。从阅读Swift中的异步执行和完成处理程序开始