From bea48db1ee2804c8885da4cdce1fab6f2a47a42c Mon Sep 17 00:00:00 2001 From: devminseok Date: Wed, 25 Dec 2024 20:15:44 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20background=20=EC=A7=84=EC=9E=85?= =?UTF-8?q?=EC=8B=9C=20LiveActivity=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=8B=A4=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/PomodoroService.swift | 13 +--- .../Feature/Feature/Sources/AppCore.swift | 67 ++++++++++++------- 2 files changed, 44 insertions(+), 36 deletions(-) diff --git a/Projects/Domain/PomodoroService/Sources/PomodoroService.swift b/Projects/Domain/PomodoroService/Sources/PomodoroService.swift index c07e059..179b44f 100644 --- a/Projects/Domain/PomodoroService/Sources/PomodoroService.swift +++ b/Projects/Domain/PomodoroService/Sources/PomodoroService.swift @@ -18,8 +18,6 @@ extension PomodoroService: DependencyKey { public static let liveValue: PomodoroService = .live() private static func live() -> PomodoroService { - - return .init( syncCategoryList: { apiClient, databaseClient in @@ -60,20 +58,13 @@ extension PomodoroService: DependencyKey { identifier: "com.pomonyang.mohanyang.update_LiveActivity", queue: nil ) { task in - print("BackgroundTask 호출!!") task.expirationHandler = { - print("BackgroundTask 끝!!") task.setTaskCompleted(success: false) } - let pomodoroActivities = liveActivityClient.protocolAdapter.getActivities(type: PomodoroActivityAttributes.self) Task { - for activity in pomodoroActivities { - await liveActivityClient.protocolAdapter.updateActivity( - type(of: activity.attributes), - id: activity.id, - content: activity.content - ) + if let firstActivity = pomodoroActivities.first { + await firstActivity.update(firstActivity.content) } task.setTaskCompleted(success: true) } diff --git a/Projects/Feature/Feature/Sources/AppCore.swift b/Projects/Feature/Feature/Sources/AppCore.swift index 881661e..a6c204d 100644 --- a/Projects/Feature/Feature/Sources/AppCore.swift +++ b/Projects/Feature/Feature/Sources/AppCore.swift @@ -19,9 +19,11 @@ import UserDefaultsClientInterface import UserNotificationClientInterface import CatServiceInterface import UserServiceInterface +import PomodoroServiceInterface import DatabaseClientInterface import StreamListenerInterface import BackgroundTaskClientInterface +import LiveActivityClientInterface import ComposableArchitecture @@ -37,9 +39,9 @@ public struct AppCore { var onboarding: OnboardingCore.State? @Presents var networkError: NetworkErrorCore.State? @Presents var requestError: RequestErrorCore.State? - + var isLoading: Bool = false - + public init() {} } @@ -62,7 +64,8 @@ public struct AppCore { @Dependency(DatabaseClient.self) var databaseClient @Dependency(StreamListener.self) var streamListener @Dependency(BackgroundTaskClient.self) var backgroundTaskClient - + @Dependency(LiveActivityClient.self) var liveActivityClient + public init() {} public var body: some ReducerOf { @@ -101,56 +104,62 @@ public struct AppCore { await send(.serverState(serverState)) } } - + case .appDelegate: return .none case .didChangeScenePhase(.background): - let request = BGAppRefreshTaskRequest(identifier: "com.pomonyang.mohanyang.update_LiveActivity") - request.earliestBeginDate = Date(timeIntervalSinceNow: 60) - - - do { - try BGTaskScheduler.shared.submit(request) - } catch { - print("BGTaskScheduler not submitted") - } return .run { send in - // 현재 타이머가 실행중이면 submit 해야함 - // + let pomodoroActivity = liveActivityClient.protocolAdapter.getActivities(type: PomodoroActivityAttributes.self).first + let pendingBGTaskRequest = await backgroundTaskClient.pendingTaskRequests().first + if let pomodoroActivity { + if let pendingBGTaskRequest { + if pendingBGTaskRequest.earliestBeginDate != pomodoroActivity.content.state.goalDatetime { + backgroundTaskClient.cancel(identifier: pendingBGTaskRequest.identifier) + await pomodoroActivity.update(pomodoroActivity.content) + try submitUpdateLiveActivityBGTask(earliestBeginDate: pomodoroActivity.content.state.goalDatetime) + } + } else { + try submitUpdateLiveActivityBGTask(earliestBeginDate: pomodoroActivity.content.state.goalDatetime) + } + } else { + if let pendingBGTaskRequest { + backgroundTaskClient.cancel(identifier: pendingBGTaskRequest.identifier) + } + } } case .didChangeScenePhase: return .none - + case .splash(.moveToHome): state.splash = nil state.home = HomeCore.State() return .none - + case .splash(.moveToOnboarding): state.splash = nil state.onboarding = OnboardingCore.State() return .none - + case .splash: return .none - + case .home: return .none - + case .onboarding(.selectCat(.presented(.namingCat(.presented(.moveToHome))))): state.onboarding = nil state.home = HomeCore.State() return .none - + case .onboarding: return .none - + case .networkError: return .none - + case .requestError(.presented(.moveToHome)): if state.onboarding != nil { state.onboarding = OnboardingCore.State() @@ -158,10 +167,10 @@ public struct AppCore { state.home = HomeCore.State() } return .none - + case .requestError: return .none - + case .serverState(let serverState): switch serverState { case .requestStarted: @@ -178,4 +187,12 @@ public struct AppCore { return .none } } + + func submitUpdateLiveActivityBGTask(earliestBeginDate: Date) throws { + let request = BGProcessingTaskRequest(identifier: "com.pomonyang.mohanyang.update_LiveActivity") + request.requiresExternalPower = false + request.requiresNetworkConnectivity = false + request.earliestBeginDate = earliestBeginDate + try backgroundTaskClient.submit(taskRequest: request) + } }