Skip to content

Conversation

@y-eonee
Copy link
Collaborator

@y-eonee y-eonee commented Dec 16, 2025

🌀 컴바인 과제

📂 시연 영상

구현

처음에 그냥 Published + Task로 네트워크 호출을 했더니 컴바인을 안쓰게 되는 코드가 되더라구요
그래서 컴바인을 사용하는 버전, 안사용하는 버전 두가지의 뷰모델을 만들었습니다.
PR에서는 컴바인을 사용하는 버전만 작성합니다. + 저는 스유로 과제했습니다

네트워크

AnyPublisher를 리턴해줍니다. 퍼블리셔에서는 model 배열을 담고있습니다

protocol BoxOfficeService_Combine {
    func fetchDailyBoxOffice()-> AnyPublisher<[DailyBoxOfficeModel], Error>
}

struct CombineBoxOfficeService: BoxOfficeService_Combine {
    let networkService =  NetworkService.shared
    
    func fetchDailyBoxOffice() -> AnyPublisher<[DailyBoxOfficeModel], Error> {
        return Future { promise in
            Task {
                do {
                    let response: DailyBoxOfficeResponseDTO =
                    try await networkService.request(endPoint: .dailyBoxOffice)
                    
                    let result = response.boxOfficeResult.dailyBoxOfficeList
                        .map { $0.toEntity() }
                    
                    promise(.success(result))
                } catch {
                    promise(.failure(error))
                }
            }
        }.eraseToAnyPublisher()
    }
}

뷰모델

저는 뷰모델타입 프로토콜을 채택해서 ViewModelType 프로토콜에서 ObservableObject를 채택해서 사용했습니다

func action(_ trigger: Input) {
        switch trigger {
        case .viewDidLoad:
            fetchDailyBoxOffice()
        }
    }
    
    private func fetchDailyBoxOffice() {
        networkService.fetchDailyBoxOffice()
            .receive(on: DispatchQueue.main)
            .sink(
                receiveCompletion: { completion in
                    if case let .failure(error) = completion {
                        print(error)
                    }
                },
                receiveValue: { [weak self] list in
                    self?.dailyBoxOfficeList = list
                }
            )
            .store(in: &cancellables)
    }

퍼블리셔를 구독해서 Published 프로퍼티 객체에 해당 값을 바인딩해줍니다. 그러면 뷰에서 ui가 갱신되게 됩니다.

참고자료

https://medium.com/@catchvarun25/mvvm-with-swiftui-combine-51edb1a011ce

@y-eonee y-eonee self-assigned this Dec 16, 2025
Copy link
Collaborator

@Yeonnies Yeonnies left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

잘봤슝!!!

스쿼트오니

import SwiftUI

struct DailyBoxOfficeView: View {
@StateObject var viewModel: DailyBoxOfficeViewModel_Combine
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 혹시 @ObjervedObject가 아닌 @StateObject 쓰신 이유가 있나요??


import SwiftUI

protocol ViewModelType: ObservableObject {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

왜 아웃풋은 따로 안만들어줬나요?? 바보 질문 미안..

import Foundation

class DailyBoxOfficeViewModel_Combine: ViewModelType {
private let networkService = CombineBoxOfficeService()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

싱글톤 패턴으로 서비스 만드셨던 거 같은데 굳이 만들어주신 이유가 있나요?? 바보 질문 죄송

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것은저의바보짓입니다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants