委托方法不会被第二次调用

delegate method does not get called second time

我正在构建一个简单的货币转换器应用程序。当 ViewController 打开时,它会从 CoinManager.swift:

调用一个函数
class ViewController: UIViewController {
    var coinManager = CoinManager()

        override func viewDidLoad() {
           super.viewDidLoad()
            
            coinManager.delegate = self
            coinManager.getCoinPrice(for: "AUD", "AZN", firstCall: true)
        }
...
}

CoinManager.swift:

protocol CoinManagerDelegate {
    func didUpdatePrice(price1: Double, currency1: String, price2: Double, currency2: String)
    func tellTableView(descriptions: [String], symbols: [String])
    func didFailWithError(error: Error)
}

struct CoinManager {

    var delegate: CoinManagerDelegate?
    let baseURL = "https://www.cbr-xml-daily.ru/daily_json.js"

    func getCoinPrice (for currency1: String,_ currency2: String, firstCall: Bool) {

        if let url = URL(string: baseURL) {

            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url) { (data, response, error) in
                if error != nil {
                    self.delegate?.didFailWithError(error: error!)
                    return
                }

                if let safeData = data {
                    if let coinData = self.parseJSON(safeData) {
                        
                        if firstCall {
                            var descriptions = [""]
                            let listOfCoins = Array(coinData.keys)
                            
                            for key in listOfCoins {
                                descriptions.append(coinData[key]!.Name)
                            }
                            descriptions.removeFirst()
                            self.delegate?.tellTableView(descriptions: descriptions, symbols: listOfCoins)
                        }

                        if let coinInfo1 = coinData[currency1] {
                            let value1 = coinInfo1.Value
                            if let coinInfo2 = coinData[currency2] {
                                let value2 = coinInfo2.Value

//this line does not do anything the second time I call getCoinPrice: 
                                self.delegate?.didUpdatePrice(price1: value1, currency1: currency1, price2: value2, currency2: currency2) 
//And this one does work
                                print("delegate:\(currency1)") 
                            } else {
                                print("no name matches currency2")
                            }
                        } else {
                            print("no name matches currency1")
                        }
                    }
                }
            }
            task.resume()
        }
    }
func ParseJSON....
}

它调用的方法(ViewController.swift):

extension ViewController: CoinManagerDelegate {

    func didUpdatePrice(price1: Double, currency1: String, price2: Double, currency2: String) {
        
        print("didUpdatePrice called")
        
        DispatchQueue.main.async {
            let price1AsString = String(price1)
            let price2AsString = String(price2)
            self.leftTextField.text = price1AsString
            self.rightTextField.text = price2AsString
            self.leftLabel.text = currency1
            self.rightLabel.text = currency2
        }
    }
...
}

最后,货币ViewController.swift:


var coinManager = CoinManager()

   @IBAction func backButtonPressed(_ sender: UIBarButtonItem) {
        dismiss(animated: true, completion: nil)
        coinManager.getCoinPrice(for: "USD", "AZN", firstCall: false)
    }

因此,当我启动该应用程序时,我在调试控制台中得到以下提示:

didUpdatePrice called
delegate:AUD

当我从 CurrencyViewController 调用 getCoinPrice() 时,委托方法没有被调用。当我在调试控制台中得到这个时,我知道我的代码通过委托函数行:

delegate:USD

我就是无法理解它。第二次调用时委托方法不起作用。即使它被相同的算法调用

能分享一下CoinManager的完整代码吗?我看到这部分

if firstCall {
  ...
}

也许这里有一些块逻辑或未处理的情况?你能分享协议的完整代码吗?

也尝试在这段代码之前打印一些东西:

if error != nil {
    self.delegate?.didFailWithError(error: error!)
        return
}

这是因为您在 CurrencyViewController 中创建了 CoinManager 的新对象,其中 delegate 未设置。因此,每次创建 CoinManager.

的新实例时,都必须设置 delegate
@IBAction func backButtonPressed(_ sender: UIBarButtonItem) {
    dismiss(animated: true, completion: nil)
    coinManager.delegate = self
    coinManager.getCoinPrice(for: "USD", "AZN", firstCall: false)
}

更新:因此,上述解决方案需要您使委托符合 CurrencyViewController。如果您正在寻找替代解决方案,您应该将 ViewControllercoinManager 的实例传递给 CurrencyViewController。为此,您需要更新以下内容。

CurrencyViewController中:

class CurrencyViewController: UIViewController {
    var coinManager: CoinManager! // you can optional unwrap if you intent to use CurrencyViewController without coinManager
    //...

ViewController中:

currencyViewController.coinManager = coinManager // passing the instance of coinManager