let url = URL(string: "https://api.coindesk.com/v1/bpi/currentprice.json")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print ("Error!")
} else {
if let content = data {
do {
let myJson = try JSONSerialization.jsonObject(with: content) as! [String:Any]
if let rates = myJson["bpi"] as? [String:Any] {
if let currency = rates["USD"] as? [String:Any] {
if let btc = currency["rate"] as? String {
DispatchQueue.main.async{
self.bitcoinlabel.text = "$" + btc
}
}
}
}
}
catch{
print(error)
}
}
}
}
task.resume()
let btcprice: Double = btc
问题出在最后一行(使用未解析的标识符'btc')。如何从数据中导出值,以便在代码块之外或其他函数中使用。
答案 0 :(得分:0)
btc
。你应该只在定义它的范围内做任何你想做的事情。
像这样:
if let btc = currency["rate"] as? String {
DispatchQueue.main.async{
self.bitcoinlabel.text = "$" + btc
let btcprice: Double = btc
// Do Stuff here with btcprice
// OR Call another func from here like someFunctionWhichUsesTheBtcprice()
// OR Add CompletionHandler in the Method definition like : completion: @escaping (()->()) and pass the function you want to call after you get the response with the method and call that function here like: completion()
}
}
另外,如果您将btcprice
声明为var btcprice: Double?
之类的类变量,则应仅在该块中指定self.btcprice = btc
。但是,只有在API返回响应后才能使用它来做任何事情,否则btcprice
将是nil
。
更新代码:
您可以使用以下内容:
func callAPI(completion: @escaping (Double) -> ()) {
// Call Your API Here...
let url = URL(string: "https://api.coindesk.com/v1/bpi/currentprice.json")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print ("Error!")
} else {
if let content = data {
do {
let myJson = try JSONSerialization.jsonObject(with: content) as! [String:Any]
if let rates = myJson["bpi"] as? [String:Any] {
if let currency = rates["USD"] as? [String:Any] {
if let btc = currency["rate"] as? String {
DispatchQueue.main.async{
self.bitcoinlabel.text = "$" + btc
if let btcDoubleValue = Double(btc) {
// This will be called when we will get the response and btc value
completion(btcDoubleValue)
}
}
}
}
}
}
catch{
print(error)
}
}
}
}
task.resume()
}
这样称呼:
self.callAPI() { (btcprice) in
// Do your stuff here
}
答案 1 :(得分:0)
你可以将它声明为实例变量,但请记住,对API的调用是异步的,因此在响应返回之前它的值不会是真实的,在类范围中声明btc
var btc: Double?
然后
if let btc = currency["rate"] as? String {
DispatchQueue.main.async{
self.bitcoinlabel.text = "$" + btc
self.btc = btc
}
}