상세 컨텐츠

본문 제목

[iOS] URLsession으로 통신하기 4탄(Delegate패턴으로 정보 전달)

카테고리 없음

by 옹홍 2021. 4. 28. 21:37

본문

extension WeatherViewController: WeatherManagerDelegate{
    
    func didUpdateWeather(_ weatherManager: WeatherManger, weather: WeatherModel) {
        DispatchQueue.main.async {
            self.temperatureLabel.text = weather.temperatureString
            self.conditionImageView.image = UIImage(systemName: weather.conditionName)
            self.cityLabel.text = weather.cityName
        }
    }
    
    func didFailWithError(error: Error) {
        print(error)
    }
}

우리는 delegate 패턴을 통해 model에서 controller로 정보를 전달할 수 있습니다.

Delegate pattern은 우리가 프로토콜을 만들고, 프로토콜을 채택한 무언가에게 delegate을 주고, 그 일을 대신하라고 전달하는 것이라고 나는 이해했다. 

protocol WeatherManagerDelegate {
    func didUpdateWeather(_ weatherManager: WeatherManger, weather: WeatherModel)
    func didFailWithError(error: Error)
    
}

만약에 WeatherManagerDelegate 이라는 프로토콜을 채택한, 클래스 혹은 struct가 있다면?? 이 클래스 혹은 struct는 이러한 함수를 꼭 구현해야합니다. 어떻게 보면 저 프로토콜을 채택하려면, 저 2 함수는 자격조건? 이라고 생각이 들게 되는거죠

우리가 delegate 패턴을 통해 모델과 controller, 뭐가 되었던 정보를 주고 받는 것은 간단합니다. 우리가 WeatherManager에서 delegate을 정의합니다. 

    var delegate: WeatherManagerDelegate?

delegate의 자료형은 WeatherManagerDelegate라는 프로토콜입니다. 그렇다면 이제 이 델리게이트를 다른 class, struct가 채택하고 있다면? manager에서 delegate.함수 문장이 시행되면, 이 문장은 델리게이트를 채택한 다른 class가 대신 수행하는 것입니다. 결국 delegate라는 말 자체가 위임한다 라는 것인데, 결국 manager에서 함수가 불려도, 다른 class나 struct가 이 일을 수행하는 거죠!!

코드 전체를 보자면

 let task = session.dataTask(with: url) { (data, response, error) in
                if let error = error {
                    self.delegate?.didFailWithError(error: error)
                    return
                }
                if let safeData = data{
                    if let weather = self.parseJSON(weatherData: safeData) {
                        self.delegate?.didUpdateWeather(self, weather: weather)
                    }
                }
            }

이런 코드가 있다면, if let safeData = data라면, 또한 parseJSON이라는 함수를 통해서 weather의 값이 생긴다면, weather의 값을 delegate?.didUpdateWeather가 실행된다. 하지만 여기서 이 함수는 다른 클래스에서 프로토콜을 채택하고 있기 때문에 그 곳에서 시행된다는 것이다.

extension WeatherViewController: WeatherManagerDelegate{
    
    func didUpdateWeather(_ weatherManager: WeatherManger, weather: WeatherModel) {
        DispatchQueue.main.async {
            self.temperatureLabel.text = weather.temperatureString
            self.conditionImageView.image = UIImage(systemName: weather.conditionName)
            self.cityLabel.text = weather.cityName
        }
    }
    
    func didFailWithError(error: Error) {
        print(error)
    }
}

여기는 Viewcontroller 부분인데, 이 뷰컨이 WeatherManagerDelegate를 채택하고 있기 때문에, 이 친구가 대신 일을 수행해줍니다. 이렇게 우리는 제이스 파싱한 데이터를 뷰컨으로 이동시킬 수 있는 것이죠!!

댓글 영역