좋아
func simpleNetworkRequest(url: URL, completion: @escaping (Result<Data, Error>) -> Void) {
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
completion(.failure(error))
return
}
guard let data = data else {
completion(.failure(NSError(domain: "No Data", code: 0, userInfo: nil)))
return
}
completion(.success(data))
}.resume()
}
아주아주 기본적인 network요청의 형식에 익숙해지기
import Foundation
// URL과 컴플리션 핸들러를 매개변수로 받는 함수. Result 타입으로 Data 또는 Error를 반환하는 구조
// @escaping 클로저를 사용해 비동기 작업의 결과를 외부로 전달함.
func simpleNetworkRequest(url: URL, completion: @escaping (Result<Data, Error>) -> Void) {
// URLSession.shared는 싱글톤 인스턴스를 사용했고
// dataTask(with:completionHandler:)는 GET 요청 기본으로 생성함.
URLSession.shared.dataTask(with: url) { data, response, error in
// 에러체크 - 네트워크 오류, 서버 오류를 잡아낸다
if let error = error {
completion(.failure(error))
return
}
// data가 nil인 경우를 검사한다. 드물게 데이터 없이 응답이 올 수 있기 때문에
// nil이면 커스텀 NSError를 생성해 실패로 처리
guard let data = data else {
// 사용자 정의 에러를 생성- 도메인, 코드, userInfo를 통해 에러의 구체적인 정보를 보여줄 수 있음.
completion(.failure(NSError(domain: "No Data", code: 0, userInfo: nil)))
return
}
// 성공적으로 데이터를 받았을 때 실행
// Result.success로 래핑하여 컴플리션 핸들러에 전달하고
completion(.success(data))
}.resume()// 생성된 태스크를 실행하기 위해 resume() 메서드를 호출함. 이 호출이 없으면 태스크가 시작되지 않는다
// 왜냐면 URLSession의 태스크가 기본적으로 일시 중단 상태로 생성되기 때문임.
}
이해하려 노력하기
만약 동일한 기능을 rxSwift를 이용하여 작성한다면
import RxSwift
import RxCocoa
// URL을 받아 Single<Data>를 반환하는 함수
func rxSimpleNetworkRequest(url: URL) -> Single<Data> {
// URLSession의 rx 확장을 사용해 데이터 요청을 Observable로 변환하고
return URLSession.shared.rx.data(request: URLRequest(url: url))
// Single로 변환하여 단일 이벤트(성공 또는 실패)만 방출하도록 함.
.asSingle()
}
훨씬 간단해진다. 별도의 에러처리가 필요하지 않고 '무엇을'에만 신경쓰고 어떻게 할것인지는 rxSwift에게 맡긴다.
대박.. 잘 보고갑니다