본문 바로가기

iOS

Swift Async - Await, Combine 원만한 합의 부탁드리겠습니다.(2)

저번 글을 쓰고 나서 그래도 Combine이 뭔진 알아야겠다 싶었습니다. 그래서 WWDC2019의 Introducing Combine을 봤습니다.

 

https://developer.apple.com/videos/play/wwdc2019/722/

 

세 줄 요약 : 1. 컴바인은 비동기 프로그래밍을 돕는 프레임워크다

 

                  2. 시간에 따른 값을 처리하기 위한 통일된 선언적인 API이다
                       (that's what Combine is, a unified declarative API for processing values over time.)

 

                  3. 타입 세이프기 때문에 런타임 대신에 컴파일에서 에러를 잡을 수 있으며, 컴포지션 우선적이기 때문에 핵심개념이 간단하고 이해하기 쉽다.

                      (Combine is also type safe, allowing us to catch errors at compile time instead of at runtime. Our main design point about Combine is that it is composition first. What that means is that the core concepts are simple and easy to understand.)

 

그리고 실제로 다른 리액티브 프로그래밍 라이브러리와 같이 함수형 프로그래밍 형태를 띄고 있었기 때문에 연산자들을 먼저 보며 공부하는 식으로 하려 했다!

(메소드형태로 사용되기 때문에 Operator 부분만 잘 익히면 Combine을 코드에 적용하기 쉬울 것이라고 생각했다ㅎ)

 

 

 

자~ 공식문서 드가자~

 

...

 

 

대충 짤을 먼저 만들긴 해봤는데, 핵심개념이 간단하고 쉽다 그랬지 연산자들까지 심플할거라곤 말 안하긴 했습니다ㅋㅋ;;;;

 

 

아무튼 설날 할머니 밥상과도 같은 Combine 공식문서의 푸짐한 인심에 제 마음도 따뜻하게 녹아내렸고, 드디어 코드를 짜기 시작합니다...

 

    func fetchCombine() -> AnyPublisher<[Challenge], Error>{
        
        Future<[Challenge], Error> {  promise in
            
            self.database.collection("Challenge")
                .getDocuments{(snapshot, error) in
// ...
                
            }
            
        }
        .eraseToAnyPublisher()
    }

 

곧 출시 예정인 앱의 내부코드이기 때문에 중략하였습니다.

 


AnyPublisher는 컴바인의 여러 오퍼레이터들을 사용하면서 생성되는 다양한 퍼블리셔타입에 대응할 수 있는 구조체입니다.



Future는 단일 데이터를 반환해주는 퍼블리셔입니다. 근데 공식문서를 읽으면서 든 의문은, Future이 컴바인의 퍼블리셔들 사이에서 유일하게 class인 퍼블리셔라는 것입니다.  왜 그래야만 했을까 해서 엄청 찾아봤지만 답을 찾지 못해서 ChatGPT에게 물어봤습니다...

 

 

한 줄 요약: 여러객체에 전달되고 참조될 수 있도록 하기 위해서 참조타입인 클래스를 썼다~

(The design of Future as a class allows it to have reference semantics, meaning it can be passed around and referenced by multiple objects.) 

 

다른 퍼블리셔들은 전달될 때 복사되기 때문에 값타입인 struct를 썼다고 합니다. (호기심 천국 끝)

 

 

코드상에 //... 로 생략된 부분에는 .promise(.success()) 클로저를 통해 Future로 생성된 result을 리턴하거나 에러처리를 할 수 있도록 했습니다.

마지막으로 eraseToAnyPublisher는 위에서 설명하였듯 다양한 퍼블리셔타입이 생길 수 있으므로 그 퍼블리셔들을 AnyPublisher로 래핑해주는 메소드입니다. 왜 erase인지는 공식문서를 보면 압니다.

 

 

 

 

 

 

이렇게 Publish를 하는 메소드를 만들었고 이후엔, Subscribe를 하는 메소드를 .sink(receiveValue:) 와 .store() 로 만들어 값을 받아오고, 구독을 그만둘 수 있도록 했습니다.

 

이렇게 공식문서를 참고하여 컴바인 프레임워크를 사용하여 아~주 간단한 네트워크 코드 작성해보았습니다.

 

이렇게 하니까 오퍼레이터들 역할도 이해가 가기 시작하고, 리액티브 프로그래밍에 조금은 친숙해진 느낌이 들었습니다!

근데...

....

어....

....


음...

...

aysnc - await가 더 간단하고 조은데 Combine 왜 씀?

(3부에서 계속)