Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
🎬 구현화면
🍿 MovieViewModel 설명
1)
@Published프로퍼티@Published는 값이 변경될 때마다 새로운 값을 방출하는 Publisher입니다ViewController는 해당 프로퍼티를 구독(subscribe) 하여 값 변경 시 자동으로 UI를 갱신합니다.
상태 변경 책임을 ViewModel 내부로 한정하고 싶어서,
private(set)을 사용하여 ViewModel 외부에서는 값을 읽기만 가능하도록 제한했어용movies: 화면에 표시할 영화 목록errorMessage: 네트워크 실패 시 전달할 에러 메시지2)
fetch(targetDate:)— ViewModel의 입력(Input)ViewController에서 호출하는 메서드로,
Combine 파이프라인을 시작하는 트리거 역할을 합니다.
화면 진입 또는 특정 이벤트 발생 시 네트워크 요청을 수행합니다.
3)
Future— 비동기 작업을 Combine으로 래핑Future는 어떤 작업을 수행한 뒤, 단 한 번의 결과(success 또는 failure)를 비동기적으로 방출하는 Publisher입니다.Apple 공식 문서
여러 값을 지속적으로 방출하는 일반적인 Publisher와 달리,‼️
한 번의 결과만 필요한 비동기 작업에 적합하다고 하더라구요
근데 영화진흥위원회 Open API 요청은 요청 → 응답 → 종료 형태의 1회성 네트워크 작업이니까요,,,
네트워크 요청을 Combine 스트림에 연결하기 위해
Future를 사용해봤습니당사실
async/await로도 충분히 구현 가능할 것 같긴해요 함 써보고 시펏서여4)
Task— async/await와 Combine 연결서비스 레이어는
async/await기반으로 구현되어 있습니다.그러나
Future의 클로저 내부에서는async함수를 직접 호출할 수 없기 때문에,Task를 사용하여 Swift Concurrency와 Combine을 연결했습니다.5) DTO → Entity 변환
이후에는 네트워크 응답으로 받은 DTO를 앱 내부에서 사용하는 Entity로 변환
6) 메인 스레드로 전달
Published프로퍼티는 UI와 직접 연결되기 때문에 값 변경은 반드시 메인 스레드에서 이루어져야 합니다.receive(on:)을 통해 이후 연산과 구독이 메인 스레드에서 실행되도록 합니다.7)
sink— 결과 구독 및 상태 업데이트sink는 Publisher를 실제로 실행시키는 구독자(Subscriber) 입니다.completion: 스트림의 성공 또는 실패를 처리receiveValue: 성공적으로 전달된 값을 처리실패 시 에러 메시지를 업데이트하고,
성공 시 영화 목록을
@Published프로퍼티에 할당8)
store(in:)— 구독 생명주기 관리Combine의 구독은 참조가 유지되지 않으면 즉시 취소됩니다.
AnyCancellable을 저장하여 ViewModel이 살아 있는 동안 Combine 스트림이 유지되도록 합니다.🎥 Input/Output이 잘 안보이는 것 같은데요?!!🤔
Input이 메서드 호출로 표현
Input struct/transform(input:)처럼 명시적으로 감싸지 않았을 뿐이죠!Output은
@Published로 바로 노출됨@Published)를 직접 Output으로 사용햇습니다그래도 Combine의 핵심 개념은 다 사용했어요!
@Published)sink)store(in:))그래도 Input/Output을 구조적으로 분리하는게 책임 분리 측면에서 더 좋은 것 같아유...흠냥