Skip to content

Commit d2fa031

Browse files
authored
[#441] Home 초기 데이터 로드 시점을 화면 생명주기에서 선택 상태 기준으로 변경한다 (#492)
* fix: Home 초기 데이터 로드 트리거를 MainView 선택 상태로 이동한다 * refactor: HomeViewModel의 메서드를 본인의 Coordinator에서 호출하는 형태로 개선 * refactor: 혹시나 하는 nil 방어 * fix: MainView의 초기 관찰 시작 시점을 onAppear로 되돌림 * fix: Home 탭 재진입 시 초기 데이터 로드가 다시 수행되도록 조정
1 parent 0941fc5 commit d2fa031

6 files changed

Lines changed: 41 additions & 27 deletions

File tree

Application/DevLogPresentation/Sources/Home/Home/HomeView.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,6 @@ struct HomeView: View {
8282
.font(.caption)
8383
.multilineTextAlignment(.center)
8484
}
85-
.onAppear {
86-
coordinator.viewModel.send(.onAppear)
87-
}
8885
.overlay {
8986
if coordinator.viewModel.state.isAppending {
9087
LoadingView()

Application/DevLogPresentation/Sources/Home/Home/HomeViewCoordinator.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ final class HomeViewCoordinator {
4545
)
4646
}
4747

48+
func loadInitialData() {
49+
viewModel.send(.loadInitialData)
50+
}
51+
4852
func makeTodoManageViewModel() -> TodoManageViewModel {
4953
TodoManageViewModel(viewModel.state.preferences)
5054
}

Application/DevLogPresentation/Sources/Home/Home/HomeViewModel.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ final class HomeViewModel: Store {
3838
}
3939

4040
enum Action {
41-
case onAppear
41+
case loadInitialData
4242
case networkStatusChanged(Bool)
4343
case setPresentation(Presentation, Bool)
4444
case setAlert(isPresented: Bool, type: AlertType? = nil)
@@ -145,7 +145,7 @@ final class HomeViewModel: Store {
145145
switch action {
146146
case .networkStatusChanged(let isConnected):
147147
state.isNetworkConnected = isConnected
148-
case .onAppear, .setPresentation, .setAlert, .setToast, .refreshWebPages,
148+
case .loadInitialData, .setPresentation, .setAlert, .setToast, .refreshWebPages,
149149
.tapTodoCategory, .orderTodoCategory, .addTodo, .updateWebPageURLInput,
150150
.addWebPage, .deleteWebPage, .undoDeleteWebPage:
151151
effects = reduceByView(action, state: &state)
@@ -274,7 +274,7 @@ private extension HomeViewModel {
274274
// swiftlint:disable cyclomatic_complexity
275275
func reduceByView(_ action: Action, state: inout State) -> [SideEffect] {
276276
switch action {
277-
case .onAppear:
277+
case .loadInitialData:
278278
return [.fetchTodoCategoryPreferences, .fetchRecentTodos, .fetchWebPages]
279279
case .refreshWebPages:
280280
return [.fetchWebPages]

Application/DevLogPresentation/Sources/Main/MainView.swift

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ struct MainView: View {
1515
@State private var homeViewCoordinator: HomeViewCoordinator
1616
@State private var todayViewCoordinator: TodayViewCoordinator
1717
@State private var profileViewCoordinator: ProfileViewCoordinator
18-
@Binding var selectedTab: MainTab
18+
@Binding var selectedTab: MainTab?
1919

2020
init(
2121
container: DIContainer,
22-
selectedTab: Binding<MainTab>
22+
selectedTab: Binding<MainTab?>
2323
) {
2424
self._coordinator = State(initialValue: MainViewCoordinator(container: container))
2525
self._homeViewCoordinator = State(initialValue: HomeViewCoordinator(container: container))
@@ -30,15 +30,22 @@ struct MainView: View {
3030

3131
var body: some View {
3232
Group {
33-
if isCompactLayout {
34-
tabView
35-
} else {
36-
sidebarView
33+
if let selectedTab {
34+
if isCompactLayout {
35+
tabView
36+
} else {
37+
sidebarView(for: selectedTab)
38+
}
3739
}
3840
}
3941
.onAppear {
4042
coordinator.mainViewModel.send(.onAppear)
4143
}
44+
.onChange(of: selectedTab) { _, newValue in
45+
if newValue == .home {
46+
homeViewCoordinator.loadInitialData()
47+
}
48+
}
4249
.alert(
4350
coordinator.mainViewModel.state.alertTitle,
4451
isPresented: mainAlertPresented
@@ -55,37 +62,37 @@ struct MainView: View {
5562
.tabItem {
5663
tabLabel(.home)
5764
}
58-
.tag(MainTab.home)
65+
.tag(MainTab.home as MainTab?)
5966

6067
todayView
6168
.tabItem {
6269
tabLabel(.today)
6370
}
64-
.tag(MainTab.today)
71+
.tag(MainTab.today as MainTab?)
6572

6673
notificationView
6774
.tabItem {
6875
tabLabel(.notification)
6976
}
7077
.badge(coordinator.mainViewModel.state.unreadPushCount)
71-
.tag(MainTab.notification)
78+
.tag(MainTab.notification as MainTab?)
7279

7380
profileView
7481
.tabItem {
7582
tabLabel(.profile)
7683
}
77-
.tag(MainTab.profile)
84+
.tag(MainTab.profile as MainTab?)
7885
}
7986
}
8087

8188
@ViewBuilder
82-
private var sidebarView: some View {
89+
private func sidebarView(for selectedTab: MainTab) -> some View {
8390
switch selectedTab.mainTabSplitStyle {
8491
case .detailOnly:
8592
NavigationSplitView {
8693
mainSidebar
8794
} detail: {
88-
selectedTabView
95+
selectedTabView(for: selectedTab)
8996
}
9097
case .contentDetail:
9198
switch selectedTab {
@@ -138,7 +145,7 @@ struct MainView: View {
138145
NavigationSplitView {
139146
mainSidebar
140147
} detail: {
141-
selectedTabView
148+
selectedTabView(for: selectedTab)
142149
}
143150
}
144151
}
@@ -155,7 +162,7 @@ struct MainView: View {
155162
}
156163

157164
@ViewBuilder
158-
private var selectedTabView: some View {
165+
private func selectedTabView(for selectedTab: MainTab) -> some View {
159166
switch selectedTab {
160167
case .home:
161168
homeView

Application/DevLogPresentation/Sources/Root/RootView.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public struct RootView: View {
1414
@Environment(\.diContainer) var container: DIContainer
1515
@State var viewModel: RootViewModel
1616
@State private var selectedRoute: Route?
17-
@State private var selectedMainTab = MainTab.home
17+
@State private var selectedMainTab: MainTab?
1818
private let widgetURLTab: (URL) -> MainTab?
1919
private let pushNotificationTodoIdPublisher: AnyPublisher<String, Never>
2020
private let clearPushNotificationRoute: () -> Void
@@ -56,16 +56,22 @@ public struct RootView: View {
5656
.preferredColorScheme(viewModel.state.theme.colorScheme)
5757
.onAppear { viewModel.send(.onAppear) }
5858
.onChange(of: viewModel.state.signIn) { _, value in
59-
guard value == false else { return }
60-
selectedMainTab = .home
59+
guard let value else { return }
60+
if value {
61+
selectedMainTab = .home
62+
} else {
63+
selectedMainTab = nil
64+
}
6165
}
6266
.onOpenURL { url in
6367
guard let mainTab = widgetURLTab(url) else { return }
6468
switch viewModel.state.signIn {
6569
case .some(false):
66-
selectedMainTab = .home
67-
case .some(true), .none:
70+
break
71+
case .some(true):
6872
selectedMainTab = mainTab
73+
case .none:
74+
break
6975
}
7076
}
7177
.alert(viewModel.state.alertTitle, isPresented: Binding(

Application/DevLogPresentation/Tests/WebPage/DeleteWebPageTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct DeleteWebPageTests {
4545
networkConnectivityUseCase: observeNetworkConnectivityUseCaseSpy
4646
)
4747

48-
homeViewModel.send(.onAppear)
48+
homeViewModel.send(.loadInitialData)
4949
await waitUntil {
5050
!homeViewModel.state.webPages.isEmpty
5151
}
@@ -97,7 +97,7 @@ struct DeleteWebPageTests {
9797
networkConnectivityUseCase: observeNetworkConnectivityUseCaseSpy
9898
)
9999

100-
homeViewModel.send(.onAppear)
100+
homeViewModel.send(.loadInitialData)
101101
await waitUntil {
102102
!homeViewModel.state.webPages.isEmpty
103103
}

0 commit comments

Comments
 (0)