Примерный порядок реализации делегатов через протоколы на примере 2-х классов QuoteAPI и ProfileController (из QuoteAPI передаём дату в ProfileController).
protocol QuoteAPIDelegate: class {
func fetchQuotes(quotesArray: [Quote])
}
// Внутри QuoteAPI
class QuoteAPI {
**weak var delegate: QuoteAPIDelegate?**
}
// Внутри QuoteAPI
func performRequest(author: String) {
let url = getURL(forAuthor: author)
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
let decoder = JSONDecoder()
let decodedData = try! decoder.decode(QuoteData.self, from: data!)
let data = decodedData
let totalQuotes = data.count - 1
for index in stride(from: 0, to: totalQuotes, by: 1) {
self.quotes.append(Quote(quoteId: data[index].quote_id, quote: data[index].quote, author: data[index].author))
}
**self.delegate?.fetchQuotes(quotesArray: self.quotes)**
}
task.resume()
}
// Внутри ProfileController
**var quoteAPI = QuoteAPI()**
override func viewDidLoad() {
super.viewDidLoad()
**quoteAPI.delegate = self**
configureUI()
}
В моём случае во viewDidLoad из класса ProfileController обращаюсь к методу performRequest() в классе QuoteAPI.
// Внутри ProfileController
**var quoteAPI = QuoteAPI()**
override func viewDidLoad() {
super.viewDidLoad()
quoteAPI.delegate = self
**quoteAPI.performRequest(author: selectedCharacter.name)**
configureUI()
}
// Внутри документа с классом ProfileController
extension ProfileController: **QuoteAPIDelegate** {
func fetchQuotes(quotesArray: [Quote]) {
DispatchQueue.main.async {
print(quotesArray) // quotesArray - дата, которую мы получим из класса **QuoteAPI**
}
}
}
Т.е. к примеру у нас есть класс QuoteAPI внутри которого есть функция performRequest(), которая содержит делегат, данные из которого мы хотим передать на ProfileController.
Тогда в ProfileController нужно вызвать функцию performRequest(), которая содержится в классе QuoteAPI (т.к. именно в этой функции используется передача данных через делегат).
Тогда делегат срабатывает (т.е. мы как бы активируем метод на другом контроллере и с этого метода "прилетает" значение на текущий контроллер). 2. Нужно понимать, что функция в классе делегате срабатывает как бы "отдельно". Т.е. если в этой функции мы во время делегирование пытаемся передать какое-то значение которое было создано ВНЕ данной функции, то просто при делегировании получим пустоту.