SniffMEET. 비동기 태스크와 액터 점검하기 (2)

메이트 요청 didTabAcceptButton과 saveMateInfo를 따라가 보니 유스케이스 실행을 위해 Task가 존재했고, Combine의 sink 클로저 안에서도 Task를 생성하고 있었다. Interactor에서 태스크를 묶으면 저장 완료를 알리는 메서드가 따로 필요해 보였다. Presenter 메서드는 async로 바꾸고, View의 sink에서는 Task를 통해 호출하도록 두었다. acceptButton.publisher(event: .touchUpInside) .sink { [weak self] in Task { await self?.presenter?.didTapAcceptButton(id: self?.profile.id ?? DogProfileDTO.example.id) self?.presenter?.closeTheView() } } .store(in: &cancellables) // RequestMatePresenter func closeTheView() { if let view { router?.dismissView(view: view) } } func didTapAcceptButton(id: UUID) async { SNMLogger.info("id: \(id)") await interactor?.saveMateInfo(id: id) } 산책 요청 및 응답 RespondWalkPresenter 산책 요청은 Task로 Interactor에 존재했고, 위치 변환은 Presenter에서 await로 처리했다. ...

January 8, 2025

SniffMEET. 비동기 태스크와 액터 점검하기 (1)

작업 내역 이번 작업에서는 Task, async/await, @MainActor가 섞여 있던 부분을 화면별로 점검했다. 앱 시작 흐름부터 프로필 등록, 메이트 목록, 산책 응답까지 비동기 경계를 다시 살펴보고, 각 화면에서 책임이 어디에 있어야 하는지 정리했다. 앱 시작 플로우 UIWindow의 루트 뷰 컨트롤러를 결정하는 흐름은 @MainActor로 두고, 그 안에서 세션 복원이 끝나기를 기다렸다. await로 대기하는 동안에는 메인 액터를 점유하지 않는다. displayInitialScreen이 MainActor 안에서 실행되는지 breakpoint로 확인했고, displayOnBoardingView는 그대로 MainActor에 남겨 두었다. // AppRouter.swift func displayInitialScreen() { Task { @MainActor in do { try await SupabaseAuthManager.shared.restoreSession() displayTabBar() } catch { displayOnBoardingView() } } } 프로필 입력 및 등록 프로필 입력 부분은 전달만 하는 역할이라 비동기 처리가 필요하지 않았다. ...

January 8, 2025