添加完成处理程序以防止结果“nil”

Posted

技术标签:

【中文标题】添加完成处理程序以防止结果“nil”【英文标题】:Adding completion handler to prevent result 'nil' 【发布时间】:2018-02-22 23:51:09 【问题描述】:
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

                                let btcprice: Double = btc
                            
                        
                    
                
            
            catch
                print(error)
            
        
    

task.resume()

如何向我的 viewDidLoad 函数添加一个完整的函数,以便 btcprice 将值 btc 作为值 (double) 而不是 nil 返回?

【问题讨论】:

viewDidLoad的签名不能修改。 您能告诉我们更多细节吗?这段代码是否已经在您的 viewDidLoad 中?您的问题是关于从 String 到 Double 的 btc 转换还是另一个问题?抱歉,我看起来有点困惑。我想了解更多信息以帮助您。 请在上下文中发布此代码。 使用 guard 而不是嵌套的 if 使您的代码更易于阅读。 thatthinginswift.com/guard-statement-swift 【参考方案1】:

正如@rmaddy 在 cmets 中建议的那样,您不能更改 ViewDidLoad 的签名。但是,您可以做的是返回“btcPrice”。

只需创建一个新函数并为其添加闭包。

func btcValue(completion: @escaping((String) -> ())) //Added Line
    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
                                    completion(btc) //Added Line
                                
                            
                        
                    
                
                catch
                    print(error)
                
            
        
    
    task.resume()
   

你可以使用这段代码在任何地方调用这个函数。

    btcValue  (btc) in
        print(btc)
    

在此处阅读有关闭包的更多信息:https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html

【讨论】:

如何在闭包之外设置一个等于 'btc' 的变量? 你不能。您必须访问闭包边界内的“btc”。 哦,我明白了。我的问题是我正在尝试使用 preform segue 在我的主视图控制器和第二个视图控制器上显示“btc”。你有什么建议吗?

以上是关于添加完成处理程序以防止结果“nil”的主要内容,如果未能解决你的问题,请参考以下文章

在 nil 对象上使用 strftime - 如何防止错误?

防止 Obj-C 代码将 `nil` 传递给具有非可选参数的 Swift 方法

清理字符串以防止相对 URI 路径

进程加锁处理,防止竞争带来的错乱结果

如何在 15 秒后从服务中启动处理程序以防止应用程序睡眠并将位置发送到 Web 服务?

runtime实现数组中不能添加nil