[TIL] fetchImage 메서드를 활용한 이미지 패치 구현

Eden·6일 전
1

TIL

목록 보기
86/92

목표

  • fetchImage(for:) 메서드를 활용하여 포켓몬 ID를 기반으로 이미지를 다운로드하고, 이를 UICollectionViewCell에 표시하기.

구현 단계

(1) NetworkManager에 fetchImage 메서드 추가

  • 포켓몬 ID를 활용해 이미지 URL을 생성하고, URLSession을 사용해 이미지를 다운로드하는 메서드 fetchImage(for:)를 구현.
  • 성공적으로 이미지를 다운로드하면 이를 UIImage로 반환.
func fetchImage(for id: Int) -> Single<UIImage> {
    return Single.create { single in
        let urlString = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/\(id).png"
        guard let url = URL(string: urlString) else {
            single(.failure(NSError(domain: "NetworkManager", code: -1, userInfo: [NSLocalizedDescriptionKey: "유효하지 않은 URL"])))
            return Disposables.create()
        }

        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            if let error = error {
                single(.failure(error))
                return
            }
            guard let data = data, let image = UIImage(data: data) else {
                single(.failure(NSError(domain: "NetworkManager", code: -1, userInfo: [NSLocalizedDescriptionKey: "이미지 로드 실패"])))
                return
            }

            single(.success(image))
        }
        task.resume()

        return Disposables.create {
            task.cancel()
        }
    }
}

(2) PokemonCell에 configure 메서드 추가

  • configure(id:) 메서드를 추가해, 네트워크 매니저를 통해 포켓몬 이미지를 다운로드하고 셀에 표시.
  • RxSwift의 disposeBag을 사용하여 메모리 관리를 효율화.
func configure(id: Int) {
    let networkManager = NetworkManager.shared
    networkManager.fetchImage(for: id)
        .observe(on: MainScheduler.instance)
        .subscribe(onSuccess: { [weak self] image in
            self?.pokemonImageView.image = image
        }, onFailure: { error in
            print(" \(id): \(error.localizedDescription)")
        })
        .disposed(by: disposeBag)
}

(3) MainViewController에서 UICollectionView 설정

  • MainViewController에서 collectionView(_:cellForItemAt:) 메서드를 수정하여 PokemonCellconfigure(id:)를 호출.
  • 포켓몬 ID는 셀의 indexPath.row를 활용하여 전달.
extension MainViewController: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 20
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PokemonCell", for: indexPath) as? PokemonCell else {
            return UICollectionViewCell()
        }
        cell.configure(id: indexPath.row + 1)
        return cell
    }
}

결과

  • 각 포켓몬의 이미지를 성공적으로 다운로드하고, UICollectionView에 렌더링.
  • RxSwift와 URLSession을 조합하여 효율적인 네트워크 요청 및 데이터 바인딩 구현.

배운 점

  • RxSwiftSingle 타입을 활용한 비동기 작업 처리 방법.
  • URLSession과 RxSwift를 결합하여 네트워크 작업을 더 간단하고 효율적으로 구현할 수 있음을 학습.
  • 네트워크 요청 실패 시 적절한 에러 처리와 디버깅 메시지를 설정하는 중요성.
profile
Frontend🌐 and iOS

0개의 댓글