将 JSON 数据中的字符串发送到函数外部的变量
Sending string from JSON data to variable outside of the function
我正在尝试从 JSON 数据中获取一个字符串并将其设置为一个变量。我的问题是变量显示为空。我正在使用 JSONDecoder 检索 JSON 数据并将字符串设置为函数外部的变量。然后我想在另一个函数中使用该变量
当我打印变量时,它仍然显示为空白,即使函数已加载。在函数中,字符串正确显示。
代码:
var filmTitle = ""
override func viewDidLoad() {
super.viewDidLoad()
loadFilms()
print(self.filmTitle) //Prints as an empty string
}
func loadFilms() {
let id = filmId
let apiKey = "97a0d64910120cbeae9df9cb675ad235"
let url = URL(string: "https://api.themoviedb.org/3/movie/\(id)?api_key=\(apiKey)&language=en-US")
let request = URLRequest(
url: url! as URL,
cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData,
timeoutInterval: 10 )
let session = URLSession (
configuration: URLSessionConfiguration.default,
delegate: nil,
delegateQueue: OperationQueue.main
)
let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
if let data = dataOrNil {
do { let details = try! JSONDecoder().decode(Details.self, from: data)
self.filmTitle = details.title
print(self.filmTitle) //string prints correctly
}
}
})
task.resume()
}
我缺少什么才能将字符串正确设置为变量?
从互联网加载数据是一种异步方法。在 loadFilms()
完成之前调用打印语句。
完成后使用回调获取数据。
func loadFilms(completion: @escaping (Details?, Error?) -> Void) {
//...
let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
if let data = dataOrNil {
do { let details = try JSONDecoder().decode(Details.self, from: data)
completion(details, nil)
} catch {
completion(nil, error)
}
})
}
通话现场:
override func viewDidLoad() {
loadFilms { details, error in
if error { //* Handle Error */ }
self.filmTitle = details.title
print(filmTitle)
}
}
Web 请求是异步的,从 CP 的角度来看,需要很长时间才能完成。当你这样称呼时:
override func viewDidLoad() {
super.viewDidLoad()
loadFilms()
print(self.filmTitle) // loadFilms() hasn't finished so `filmTitle` is empty
}
最好在filmTitle
上设置一个属性观察者:
var filmTitle: String? = nil {
didSet {
print(filmTitle)
Dispatch.main.async {
// update your GUI
}
}
}
这个问题的解决方案是在数据设置到数组后,在解码器函数中重新加载数组被发送到的集合视图。
我正在尝试从 JSON 数据中获取一个字符串并将其设置为一个变量。我的问题是变量显示为空。我正在使用 JSONDecoder 检索 JSON 数据并将字符串设置为函数外部的变量。然后我想在另一个函数中使用该变量
当我打印变量时,它仍然显示为空白,即使函数已加载。在函数中,字符串正确显示。
代码:
var filmTitle = ""
override func viewDidLoad() {
super.viewDidLoad()
loadFilms()
print(self.filmTitle) //Prints as an empty string
}
func loadFilms() {
let id = filmId
let apiKey = "97a0d64910120cbeae9df9cb675ad235"
let url = URL(string: "https://api.themoviedb.org/3/movie/\(id)?api_key=\(apiKey)&language=en-US")
let request = URLRequest(
url: url! as URL,
cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData,
timeoutInterval: 10 )
let session = URLSession (
configuration: URLSessionConfiguration.default,
delegate: nil,
delegateQueue: OperationQueue.main
)
let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
if let data = dataOrNil {
do { let details = try! JSONDecoder().decode(Details.self, from: data)
self.filmTitle = details.title
print(self.filmTitle) //string prints correctly
}
}
})
task.resume()
}
我缺少什么才能将字符串正确设置为变量?
从互联网加载数据是一种异步方法。在 loadFilms()
完成之前调用打印语句。
完成后使用回调获取数据。
func loadFilms(completion: @escaping (Details?, Error?) -> Void) {
//...
let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
if let data = dataOrNil {
do { let details = try JSONDecoder().decode(Details.self, from: data)
completion(details, nil)
} catch {
completion(nil, error)
}
})
}
通话现场:
override func viewDidLoad() {
loadFilms { details, error in
if error { //* Handle Error */ }
self.filmTitle = details.title
print(filmTitle)
}
}
Web 请求是异步的,从 CP 的角度来看,需要很长时间才能完成。当你这样称呼时:
override func viewDidLoad() {
super.viewDidLoad()
loadFilms()
print(self.filmTitle) // loadFilms() hasn't finished so `filmTitle` is empty
}
最好在filmTitle
上设置一个属性观察者:
var filmTitle: String? = nil {
didSet {
print(filmTitle)
Dispatch.main.async {
// update your GUI
}
}
}
这个问题的解决方案是在数据设置到数组后,在解码器函数中重新加载数组被发送到的集合视图。