POP를 준수하면서 프로젝트를 진행하던 중 API에서 데이터를 받아오는 작업을 해야 할때, 평소 같으면 해당 작업을 담당하는 클래스를 하나 만들어서 작업을 하겠지만, POP를 이용한 프로젝트를 하던 참이였길래, 별 생각 없이 프로토콜을 우선적으로 구현하고 있었습니다. 그런데 해당 프로젝트에서는 코드를 재사용할 필요가 없을때에도 프로토콜로 추상화를 해야하나 이 생각이 들었습니다.
final class NetworkManager{
static let shared = NetworkManager()
func fetchImageList(url: String, completion : @escaping ([ContentResponse]?) -> ()){
guard let url = URL(string: url) else { return }
URLSession.shared.dataTask(with: url) { data, response, error in
if error != nil {
completion(nil)
} else if let data = data {
guard let imageList = try? JSONDecoder().decode([ContentResponse].self, from: data) else { return }
completion(imageList)
}
}.resume()
}
func fetchImage(url: String, completion: @escaping (UIImage)->Void){
guard let url = URL(string: url) else { return }
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil, let image = UIImage(data: data) else { return }
completion(image)
}.resume()
}
}
서버 API에서 이미지 리스트를 받고, 이미지 URL로 이미지를 받아오는 역할을 가진 NetworkManager가 있습니다. 이걸 이제 프로토콜로 기능별로 분리를 해서 프로토콜 지향적으로 구현해 보겠습니다.
protocol FetchImageListable {
func fetchImageList(url: String, completion : @escaping ([ContentResponse]?) -> ())
}
extension FetchImageListable {
func fetchImageList(url: String, completion : @escaping ([ContentResponse]?) -> ()) {
guard let url = URL(string: url) else { return }
URLSession.shared.dataTask(with: url) { data, response, error in
if error != nil {
completion(nil)
} else if let data = data {
guard let imageList = try? JSONDecoder().decode([ContentResponse].self, from: data) else { return }
completion(imageList)
}
}.resume()
}
}
protocol FetchImagable {
func fetchImage(url: String, completion: @escaping (UIImage)->Void)
}
extension FetchImagable {
func fetchImage(url: String, completion: @escaping (UIImage)->Void) {
guard let url = URL(string: url) else { return }
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil, let image = UIImage(data: data) else { return }
completion(image)
}.resume()
}
}
final class NetworkManager: FetchImagable, FetchImageListable {
static let shared = NetworkManager()
}
프로토콜로 서버에서 이미지 리스트를 가져오는 기능, 이미지 url로 이미지를 가져오는 기능을 분리시켜서 NetworkManager가 각 프로토콜을 채택을 하게 해서 기능을 사용할 수 있게 되었습니다. 해당 기능을 다른 곳에서 사용을 해야 할때 해당 프로토콜을 채택하기만 한다면 해당 기능을 사용 할 수 있게 되었지만, 지금 진행하고 있는 프로젝트에서는 NetworkManager에서만 해당 기능을 사용합니다. 그래서 공통적인 코드만 프로토콜로 추상화 하고 그 외의 기능들은 굳이 프로토콜로 추상화 하지 않아도 되지 않아도 될것 같네요.
'iOS > swift' 카테고리의 다른 글
프로토콜 지향 프로그래밍을 이용한 프로젝트를 진행해보자 (2) (0) | 2022.08.14 |
---|---|
프로토콜 지향 프로그래밍을 이용한 프로젝트를 진행해보자 (1) (0) | 2022.08.13 |
AnyObject와 Protocol (0) | 2022.07.24 |
약한참조, 강한참조 (weak, strong) (0) | 2022.06.11 |
Swift에서의 startsWith 구현 (0) | 2021.09.10 |