Я изучаю Swift, я хочу передать данные API Json в viewController, используя делегат и протокол:

В viewController:

  class exchangeViewController: UIViewController { 

var exchange = Exchange(baseUri: "http://data.fixer.io/api/latest?access_key=", apiKey: "apiKey")
@IBOutlet weak var inputEuro: UITextField!
@IBOutlet weak var getDollar: UILabel!
override func viewDidLoad() {
    super.viewDidLoad()
    
    exchange.delegate? = self
}

@IBAction func exchangeCurrency(_ sender: UIButton) {
    print("button1")
    exchange.fitchData()
    print("button2")
} }


extension exchangeViewController: ExchangeCurrencyDelegate {
func didRetriveDollarvalue(dollar: Dollar) {
  
        print(dollar.base + " e1")
        self.getDollar.text = dollar.base
        print(dollar.base + " e2")
      }       
   }

В модельном классе:

protocol ExchangeCurrencyDelegate{
func didRetriveDollarvalue(dollar: Dollar)    }

class Exchange{
var delegate : ExchangeCurrencyDelegate?
var baseUri : String
var apiKey  : String

init(baseUri: String, apiKey: String){
    self.baseUri = baseUri
    self.apiKey = apiKey
}
func fitchData(){
    
    let url = URL(string: baseUri + apiKey)
    
    let session = URLSession(configuration: .default)
    
    let task = session.dataTask(with: url!, completionHandler: taskHandler(data:urlresponse:error:))
    
    task.resume()
}

func taskHandler(data: Data?, urlresponse: URLResponse?, error: Error?) -> Void{
    do {
        
        let dollarValue:Dollar = try JSONDecoder().decode(Dollar.self, from: data!)
       
            print(dollarValue.base + " a")
            delegate?.didRetriveDollarvalue(dollar: dollarValue)
            print(dollarValue.base + " b")
     
        
    }
    catch {
        print(error)
    }
}  }

В долларовой структуре:

struct Dollar: Decodable{
var base: String }

Когда я запускаю это приложение, я могу напечатать: кнопка1, кнопка2, DollarValue.base + "а", DollarValue.base + "b", но я не могу выполнить протокол didRetriveDollar в расширении exchangeViewController.

Когда я использую точку останова, программа выходит за рамки делегата?.didRetriveDollarvalue(dollar: DollarValue) в классе модели. Может ли кто-нибудь найти, где я ошибаюсь? Спасибо Извините, если мой уровень английского недостаточно хорош.

0
Mo Olwan 3 Фев 2022 в 12:56
Вы проверили, является ли переменная delegate nil или нет?
 – 
udi
3 Фев 2022 в 13:49
Да, недавно я проверял это, ноль, но я не знаю, почему?
 – 
Mo Olwan
3 Фев 2022 в 13:58
Я удалил "?" из «exchange.delegate? = self», это работает, но отображается другая ошибка
 – 
Mo Olwan
3 Фев 2022 в 14:04

2 ответа

Лучший ответ

Кажется, вы неправильно настраиваете свой делегат Exchange в своем методе viewDidLoad:

exchange.delegate? = self

Попробуйте изменить его на:

exchange.delegate = self
0
frank 3 Фев 2022 в 13:56
1
Да, я удалил "?", спасибо, Фрэнк Шмитт.
 – 
Mo Olwan
3 Фев 2022 в 14:10

Для решения этой ошибки я удалил "?" от exchange.delegate? = self, и я добавил: DispatchQueue.main.async {.....}. Этот ответ заставляет код работать. Спасибо

0
Mo Olwan 3 Фев 2022 в 15:07