과제 제출을 하고 추가적으로
URLSession을 사용해보고 싶어서 공부해보았다.
typealias NetworkCompletion = (Result<Poketmon, NetworkError>) -> Void
// 네트워킹 요청하는 함수
func fetchRandomPoketmonData(completion: @escaping NetworkCompletion) {
let randomNum = Int.random(in: 1...1000)
let urlString = "\(requestUrl)\(randomNum)"
performRequest(with: urlString) { result in
completion(result)
}
}
// 실제 Request하는 함수 (비동기적 실행 ===> 클로저 방식으로 끝난 시점을 전달 받도록 설계)
private func performRequest(with urlString: String, completion: @escaping NetworkCompletion) {
print(#function)
// URL구조체 만들기
guard let url = URL(string: urlString) else { return }
let session = URLSession(configuration: .default)
// get 만 쓸 때 -> dataTask(with: url)
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
completion(.failure(.networkingError))
return
}
guard let safeData = data else {
completion(.failure(.dataError))
return
}
// 데이터 분석하기
if let poketmon = self.parseJSON(safeData) {
print("Parse 실행")
completion(.success(poketmon))
} else {
print("Parse 실패")
completion(.failure(.parseError))
}
}
task.resume()
}
// 받아본 데이터 분석하는 함수 (동기적 실행)
private func parseJSON(_ data: Data) -> Poketmon? {
print(#function)
// 성공
do {
// 우리가 만들어 놓은 구조체(클래스 등)로 변환하는 객체와 메서드
// (JSON 데이터 ====> PoketmonData 클래스)
return try JSONDecoder().decode(Poketmon.self, from: data)
// 실패
} catch {
print(error.localizedDescription)
return nil
}
}
네트워크 매니저에 fetch 메서드와 request 메서드를 구현하였다.
그 후 뷰 파일 안에서 LoadImage 메서드를 추가하였다.
// URL ===> 이미지를 셋팅하는 메서드
// 이미지의 url을 먼저 받고 그 url로 이미지를 한번 더 요청함
private func loadImage() {
guard let urlString = self.imageUrl, let url = URL(string: urlString) else { return }
DispatchQueue.global().async {
// url을 가지고 서버랑 통신하는 생성자, 동기적으로 되어있기 때문에 비동기처리를 따로 해줘야함
guard let data = try? Data(contentsOf: url) else { return }
DispatchQueue.main.async {
self.randomImageView.image = UIImage(data: data)
}
}
}
버튼에서 랜덤이미지를 받아오는 코드
@objc func randomButtonTapped(_ sender: UIButton) {
networkManager.fetchRandomPoketmonData { [weak self] result in
guard let self else { return }
DispatchQueue.main.async {
switch result {
case .success(let poketmon):
// 이미지 URL 설정
if let imageUrl = poketmon.sprites?.other?.home?.imageUrl {
self.phoneBookView.imageUrl = imageUrl
} else {
print("이미지 URL 없음")
}
case .failure(let error):
print("포켓몬 데이터 로드 실패: \(error)")
}
}
}
}
이렇게 하면 URLSession 으로도 데이터를 받아올 수 있게 된다.
아직 더 공부가 필요한 부분이 많다.
'내일배움캠프 iOS' 카테고리의 다른 글
UIKit) TIL # 41 팀 프로젝트 - 영화상영정보 앱, API 분석 (1) | 2024.12.16 |
---|---|
UIKit) TIL # 40 팀 프로젝트 발제 - 영화상영정보 앱 (1) | 2024.12.13 |
UIKit) TIL # 38 포켓몬 연락처 앱 과제 마무리, 트러블 슈팅 (0) | 2024.12.11 |
UIKit) TIL # 36 포켓몬 연락처 앱 과제 (Lv 1 ~ 4) (1) | 2024.12.09 |
UIKit) TIL # 35 날씨앱 클론, 과제 맛보기 (0) | 2024.12.06 |