Skip to content

Commit 2916a1a

Browse files
committed
fix: 세션 복구 시 위젯 동기화 트리거 추가
1 parent f7d7834 commit 2916a1a

4 files changed

Lines changed: 136 additions & 0 deletions

File tree

Application/DevLogApp/Sources/App/Assembler/AppLayerAssembler.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ final class AppLayerAssembler: Assembler {
2121
snapshotUpdater: container.resolve(WidgetSnapshotUpdater.self)
2222
)
2323
}
24+
container.register(WidgetSessionSyncHandler.self) {
25+
WidgetSessionSyncHandler(
26+
authService: container.resolve(AuthService.self),
27+
widgetSyncEventBus: container.resolve(WidgetSyncEventBus.self)
28+
)
29+
}
2430
container.register(FCMTokenSyncHandler.self) {
2531
FCMTokenSyncHandler(
2632
userService: container.resolve(UserService.self)

Application/DevLogApp/Sources/App/Delegate/AppDelegate.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
3030
_ = container.resolve(FCMTokenSyncHandler.self)
3131
_ = container.resolve(UserTimeZoneSyncHandler.self)
3232
_ = container.resolve(WidgetSyncEventHandler.self)
33+
_ = container.resolve(WidgetSessionSyncHandler.self)
3334

3435
// 알림 권한 요청
3536
UNUserNotificationCenter.current().delegate = self
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// WidgetSessionSyncHandler.swift
3+
// DevLog
4+
//
5+
// Created by opfic on 6/1/26.
6+
//
7+
8+
import Combine
9+
import DevLogData
10+
11+
final class WidgetSessionSyncHandler {
12+
private let authService: AuthService
13+
private let widgetSyncEventBus: WidgetSyncEventBus
14+
private var hasRequestedWidgetSync = false
15+
private var cancellables = Set<AnyCancellable>()
16+
17+
init(
18+
authService: AuthService,
19+
widgetSyncEventBus: WidgetSyncEventBus
20+
) {
21+
self.authService = authService
22+
self.widgetSyncEventBus = widgetSyncEventBus
23+
24+
authService.observeSignedIn()
25+
.removeDuplicates()
26+
.sink { [weak self] isSignedIn in
27+
self?.handleSessionUpdate(isSignedIn: isSignedIn)
28+
}
29+
.store(in: &cancellables)
30+
}
31+
}
32+
33+
private extension WidgetSessionSyncHandler {
34+
func handleSessionUpdate(isSignedIn: Bool) {
35+
guard isSignedIn else {
36+
hasRequestedWidgetSync = false
37+
return
38+
}
39+
40+
guard hasRequestedWidgetSync == false else {
41+
return
42+
}
43+
44+
hasRequestedWidgetSync = true
45+
widgetSyncEventBus.publish(.syncRequested)
46+
}
47+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//
2+
// WidgetSessionSyncHandlerTests.swift
3+
// DevLogAppTests
4+
//
5+
// Created by opfic on 6/1/26.
6+
//
7+
8+
import Combine
9+
import Testing
10+
import DevLogData
11+
@testable import DevLog
12+
13+
struct WidgetSessionSyncHandlerTests {
14+
@Test("로그인 세션 true 첫 진입에서만 위젯 초기 동기화를 요청한다")
15+
func 로그인_세션_true_첫_진입에서만_위젯_초기_동기화를_요청한다() {
16+
let authServiceSpy = AuthServiceSpy()
17+
let widgetSyncEventBusSpy = WidgetSyncEventBusSpy()
18+
let widgetSessionSyncHandler = WidgetSessionSyncHandler(
19+
authService: authServiceSpy,
20+
widgetSyncEventBus: widgetSyncEventBusSpy
21+
)
22+
23+
authServiceSpy.send(true)
24+
authServiceSpy.send(true)
25+
26+
#expect(widgetSyncEventBusSpy.events == [.syncRequested])
27+
_ = widgetSessionSyncHandler
28+
}
29+
30+
@Test("로그아웃 이후 재로그인 시 위젯 초기 동기화를 다시 요청한다")
31+
func 로그아웃_이후_재로그인_시_위젯_초기_동기화를_다시_요청한다() {
32+
let authServiceSpy = AuthServiceSpy()
33+
let widgetSyncEventBusSpy = WidgetSyncEventBusSpy()
34+
let widgetSessionSyncHandler = WidgetSessionSyncHandler(
35+
authService: authServiceSpy,
36+
widgetSyncEventBus: widgetSyncEventBusSpy
37+
)
38+
39+
authServiceSpy.send(true)
40+
authServiceSpy.send(false)
41+
authServiceSpy.send(true)
42+
43+
#expect(widgetSyncEventBusSpy.events == [.syncRequested, .syncRequested])
44+
_ = widgetSessionSyncHandler
45+
}
46+
}
47+
48+
private final class AuthServiceSpy: AuthService {
49+
private let currentValueSubject = CurrentValueSubject<Bool, Never>(false)
50+
51+
var uid: String? { nil }
52+
var providerIDs: [String] { [] }
53+
var currentUserEmail: String? { nil }
54+
var providerCount: Int { 0 }
55+
56+
func observeSignedIn() -> AnyPublisher<Bool, Never> {
57+
currentValueSubject.eraseToAnyPublisher()
58+
}
59+
60+
func beginSignIn() { }
61+
func completeSignIn() { }
62+
func cancelSignIn() { }
63+
func getProviderID() async throws -> String? { nil }
64+
func deleteCurrentUser() async throws { }
65+
func clearCurrentSession() async throws { }
66+
67+
func send(_ isSignedIn: Bool) {
68+
currentValueSubject.send(isSignedIn)
69+
}
70+
}
71+
72+
private final class WidgetSyncEventBusSpy: WidgetSyncEventBus {
73+
private(set) var events = [WidgetSyncEvent]()
74+
75+
func publish(_ event: WidgetSyncEvent) {
76+
events.append(event)
77+
}
78+
79+
func observe() -> AnyPublisher<WidgetSyncEvent, Never> {
80+
Empty().eraseToAnyPublisher()
81+
}
82+
}

0 commit comments

Comments
 (0)