Combine을 통해 API 데이터를 불러오자!
Combine + API
Combine,API
Combine을 통해 API 통신을 해보자
- Publisher 생성
- 어떠한 패키지에 대한 매월 정기구독을 가입함
URLSession.shared.dataTaskPublisher(for: url)
- 어떠한 패키지에 대한 매월 정기구독을 가입함
- subscribe publisher을 background Thread로 옮겨줌
- 고객이 주문하면 회사는 패키지를 공장에서 생산함
.subscribe(on: DispatchQueue.global(qos: .background))
- 고객이 주문하면 회사는 패키지를 공장에서 생산함
- Main Thread에서 수신함
- 회사는 패키지를 배송하고 고객은 상품을 전달받음
.receive(on: DispatchQueue.main) // UI가 업데이트 되었다는 의미
- 회사는 패키지를 배송하고 고객은 상품을 전달받음
- tryMap (data가 있는지 없는지 상태가 좋은지 확인)
- 사용자는 패키지 상자의 상태가 손상되었는지 확인함
.tryMap { data, response in // 실패 및 오류를 야기할 수 있는 맵 //some code }
.tryMap { data, response -> Data in guard let response = response as? HTTPURLResponse, response.statusCode >= 200 && response.statusCode < 300 else { throw URLError(URLError.Code) } return }
- 사용자는 패키지 상자의 상태가 손상되었는지 확인함
- decode (데이터를 PostModel로 디코딩)
- 상자를 열고 항목이 올바른지 확인함
.decode(type: [PostModel].self, decoder: JSONDecoder())
- 상자를 열고 항목이 올바른지 확인함
- sink(항목을 앱에 추가한다.)
- 구입한 항목을 사용함!
.sink { completion in print("Completion: \(completion)") } receiveValue: { returnedPost in self.posts = returnedPost // 강한 참조 }
.sink { completion in print("Completion: \(completion)") } receiveValue: { [weak self] returnedPost in self?.posts = returnedPost // 약한 참조 }
- 구입한 항목을 사용함!
- store(필요한 경우 구독을 취소함)
- 위 구독은 언제든지 취소가 가능함
// ViewModel에서 `var cancellables = Set<AnyCancellable>()` 코드 추가 .store(in: &cancellables)
- 위 구독은 언제든지 취소가 가능함
추상화
- Combine을 통해 API를 호출할 때에는 추상화를 작업하는 것이 좋습니다. url query에 따라서 받아오는 값이 달라지기 때문에 여러 경우의 수를 하나하나 작성해 줄 수 없기 때문입니다. 그렇다면 Combine을 통한 API 추상화에는 어떠한 요소들이 필요한지 알아보도록 하겠습니다.
Extension
- URLSession
- URLComponents
Protocol
- APIProtocol
- url: URLComponents
Providier
-
APIProtocol을 conform하는 Provider
- SearchAPIProvider
- LookupAPIProvider
- Protocol
- APIProtocol
- URLComponents
- SearchAPIProvider : APIProtocol
- props
- url : URLComponents
- methods
- -> AnyPublisher return하는거 만들고
- props
- ViewModel
- SearchAPIProvider 호출
- methods. 쓰면서 동시에 .sink