From 890322a2c69edaf48c46065e53b2a751f77e4e67 Mon Sep 17 00:00:00 2001 From: Safari <91936941+Siwon-L@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:45:53 +0900 Subject: [PATCH] =?UTF-8?q?[D-3]=20Fix=20widget=20deep=20link=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0=20(530)=20(#81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: deep link 문제 해결 * fix: deep link noti 전송 시 userInfo를 통해 agencyID 전송 * feat: Widget LinkManager 구현 --- Projects/App/Sources/AppCoordinator.swift | 5 +++-- Projects/App/Sources/DIContainer.swift | 16 +++++---------- Projects/App/Sources/SceneDelegate.swift | 13 +++++++++--- .../Sources/Model/LinkManager.swift | 17 ++++++++++++++++ .../Sources/Widgets/MainWidget.swift | 6 +++--- .../Sources/Widgets/OCRWidget.swift | 2 +- .../Sources/Widgets/SecondWidget.swift | 4 ++-- .../Core/Core/Sources/DeepLinkManager.swift | 13 ++++++++++-- .../Main/Sources/MainDIContainer.swift | 2 +- .../Main/Sources/MainTapViewController.swift | 20 +++++++++---------- 10 files changed, 63 insertions(+), 35 deletions(-) create mode 100644 Projects/App/WidgetExtension/Sources/Model/LinkManager.swift diff --git a/Projects/App/Sources/AppCoordinator.swift b/Projects/App/Sources/AppCoordinator.swift index ce0a4b1..be0b9d3 100644 --- a/Projects/App/Sources/AppCoordinator.swift +++ b/Projects/App/Sources/AppCoordinator.swift @@ -7,12 +7,13 @@ import DesignSystem final class AppCoordinator: Coordinator { var navigationController: UINavigationController - var diContainer: AppDIContainer = AppDIContainer() + let diContainer: AppDIContainer weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] - init(navigationController: UINavigationController) { + init(navigationController: UINavigationController, diContainer: AppDIContainer) { self.navigationController = navigationController + self.diContainer = diContainer } func start(animated: Bool) { diff --git a/Projects/App/Sources/DIContainer.swift b/Projects/App/Sources/DIContainer.swift index 5029dac..d48ad84 100644 --- a/Projects/App/Sources/DIContainer.swift +++ b/Projects/App/Sources/DIContainer.swift @@ -7,27 +7,21 @@ import MyPageFeature import Core final class AppDIContainer { - - private let localStorage: LocalStorageInterface - private let networkManager: NetworkManagerInterfacae - private let tokenIntercepter: TokenRequestIntercepter - let signDIContainer: SignDIContainer let mainDIContainer: MainDIContainer - init() { - self.localStorage = LocalStorage() - self.networkManager = NetworkManager() + init( + localStorage: LocalStorageInterface, + networkManager: NetworkManagerInterfacae + ) { - self.tokenIntercepter = TokenRequestIntercepter( + (networkManager as? NetworkManager)?.tokenIntercepter = TokenRequestIntercepter( localStorage: localStorage, tokenRepository: TokenRepository( networkManager: networkManager, localStorage: localStorage ) ) - - (networkManager as? NetworkManager)?.tokenIntercepter = tokenIntercepter self.signDIContainer = SignDIContainer( localStorage: localStorage, diff --git a/Projects/App/Sources/SceneDelegate.swift b/Projects/App/Sources/SceneDelegate.swift index 0f7927a..f6f4bd9 100644 --- a/Projects/App/Sources/SceneDelegate.swift +++ b/Projects/App/Sources/SceneDelegate.swift @@ -4,6 +4,10 @@ import Core import DesignSystem class SceneDelegate: UIResponder, UIWindowSceneDelegate { + private let localStorage = LocalStorage() + private let networkManager = NetworkManager() + private lazy var diContainer = AppDIContainer(localStorage: localStorage, networkManager: networkManager) + private var appCoordinator: AppCoordinator? var window: UIWindow? @@ -17,7 +21,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { self.window?.makeKeyAndVisible() self.window?.rootViewController = navigationController - self.appCoordinator = AppCoordinator(navigationController: navigationController) + self.appCoordinator = AppCoordinator( + navigationController: navigationController, + diContainer: diContainer + ) appCoordinator?.start(animated: false) self.scene(scene, openURLContexts: connectionOptions.urlContexts) @@ -25,9 +32,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { guard let url = URLContexts.first?.url else { return } - + if url.absoluteString.contains("widget://") { - DeepLinkManager.setDestination(url.absoluteString) + DeepLinkManager.setDestination(url.absoluteString, agencyID: localStorage.selectedAgency) } else { KakaoAuthManager.shared.openURL(url) } diff --git a/Projects/App/WidgetExtension/Sources/Model/LinkManager.swift b/Projects/App/WidgetExtension/Sources/Model/LinkManager.swift new file mode 100644 index 0000000..85a609e --- /dev/null +++ b/Projects/App/WidgetExtension/Sources/Model/LinkManager.swift @@ -0,0 +1,17 @@ +import Foundation + +enum LinkManager { + case ocr + case ledgerDetail + case createLedger + + var url: URL { + let urlString: String + switch self { + case .ocr: urlString = "widget://OCR" + case .ledgerDetail: urlString = "widget://LedgerDetail" + case .createLedger: urlString = "widget://CreateLedger" + } + return URL(string: urlString)! + } +} diff --git a/Projects/App/WidgetExtension/Sources/Widgets/MainWidget.swift b/Projects/App/WidgetExtension/Sources/Widgets/MainWidget.swift index 2044ecd..ff060a1 100644 --- a/Projects/App/WidgetExtension/Sources/Widgets/MainWidget.swift +++ b/Projects/App/WidgetExtension/Sources/Widgets/MainWidget.swift @@ -24,7 +24,7 @@ struct MainWidgetEntryView: View { var body: some View { VStack { - Link(destination: URL(string: "widget://CreateLedger")!) { + Link(destination: LinkManager.createLedger.url) { HStack(alignment: .center) { Text("\(entry.name)에 오늘 사용한 금액 입력") .bold() @@ -43,7 +43,7 @@ struct MainWidgetEntryView: View { Spacer() HStack { - Link(destination: URL(string: "widget://OCR")!) { + Link(destination: LinkManager.ocr.url) { HStack { Spacer() Text("영수증 스캔") @@ -56,7 +56,7 @@ struct MainWidgetEntryView: View { Divider() .background(Color(uiColor: Colors.Gray._5)) - Link(destination: URL(string: "widget://LedgerDetail")!) { + Link(destination: LinkManager.ledgerDetail.url) { HStack { Spacer() Text("회비 내역 확인") diff --git a/Projects/App/WidgetExtension/Sources/Widgets/OCRWidget.swift b/Projects/App/WidgetExtension/Sources/Widgets/OCRWidget.swift index dc4e13a..c37d620 100644 --- a/Projects/App/WidgetExtension/Sources/Widgets/OCRWidget.swift +++ b/Projects/App/WidgetExtension/Sources/Widgets/OCRWidget.swift @@ -36,7 +36,7 @@ struct OCRWidgetEntryView: View { .font(.system(size: 16, weight: .bold)) } .padding(.vertical, 20) - .widgetURL(URL(string: "widget://OCR")) + .widgetURL(LinkManager.ocr.url) .widgetBackground(Color(uiColor: Colors.Gray._1)) } } diff --git a/Projects/App/WidgetExtension/Sources/Widgets/SecondWidget.swift b/Projects/App/WidgetExtension/Sources/Widgets/SecondWidget.swift index 104242a..0142709 100644 --- a/Projects/App/WidgetExtension/Sources/Widgets/SecondWidget.swift +++ b/Projects/App/WidgetExtension/Sources/Widgets/SecondWidget.swift @@ -48,7 +48,7 @@ struct SecondWidgetEntryView: View { } HStack(spacing: 10) { - Link(destination: URL(string: "widget://OCR")!) { + Link(destination: LinkManager.ocr.url) { Text("영수증 스캔") .font(.system(size: 12, weight: .bold)) .foregroundColor(Color(uiColor: Colors.White._1)) @@ -59,7 +59,7 @@ struct SecondWidgetEntryView: View { .cornerRadius(10) } - Link(destination: URL(string: "widget://LedgerDetail")!) { + Link(destination: LinkManager.ledgerDetail.url) { Text("회비 내역 확인") .font(.system(size: 12, weight: .bold)) .foregroundColor(Color(uiColor: Colors.Blue._4)) diff --git a/Projects/Core/Core/Sources/DeepLinkManager.swift b/Projects/Core/Core/Sources/DeepLinkManager.swift index 500d962..7ea9f01 100644 --- a/Projects/Core/Core/Sources/DeepLinkManager.swift +++ b/Projects/Core/Core/Sources/DeepLinkManager.swift @@ -5,11 +5,20 @@ public struct DeepLinkManager { public static var destination: String? // OCR, CreateLedger, LedgerDetail - public static func setDestination(_ urlString: String) { + public static func setDestination(_ urlString: String, agencyID: Int?) { let query = urlString.replacingOccurrences(of: "widget://", with: "") destination = query - NotificationCenter.default.post(name: .init("deeplink"), object: nil, userInfo: ["query": query]) + guard let agencyID else { return } + + NotificationCenter.default.post( + name: .init("deeplink"), + object: nil, + userInfo: [ + "query": query, + "agencyID": agencyID + ] + ) } public static func clear() { diff --git a/Projects/Feature/Main/Sources/MainDIContainer.swift b/Projects/Feature/Main/Sources/MainDIContainer.swift index 1ffeb99..6537f1f 100644 --- a/Projects/Feature/Main/Sources/MainDIContainer.swift +++ b/Projects/Feature/Main/Sources/MainDIContainer.swift @@ -39,7 +39,7 @@ public final class MainDIContainer { } func mainTab(with coordinator: Coordinator) -> MainTapViewController { - let tabVC = MainTapViewController(agencyID: localStorage.selectedAgency) + let tabVC = MainTapViewController() tabVC.coordinator = coordinator tabVC.setViewControllers( [agencyTab(with: coordinator), diff --git a/Projects/Feature/Main/Sources/MainTapViewController.swift b/Projects/Feature/Main/Sources/MainTapViewController.swift index 4275c47..435060d 100644 --- a/Projects/Feature/Main/Sources/MainTapViewController.swift +++ b/Projects/Feature/Main/Sources/MainTapViewController.swift @@ -9,10 +9,8 @@ import RxSwift public final class MainTapViewController: UITabBarController { private let disposeBag = DisposeBag() weak var coordinator: Coordinator? - private let agencyID: Int? - public init(agencyID: Int?) { - self.agencyID = agencyID + public init() { super.init(nibName: nil, bundle: nil) } @@ -67,15 +65,17 @@ public final class MainTapViewController: UITabBarController { private func observeNotification() { NotificationCenter.default.rx .notification(.init("deeplink")) - .compactMap { $0.userInfo?["query"] as? String } - .bind(with: self) { owner, query in - guard let agencyID = owner.agencyID else { return } - - switch query { + .compactMap { noti -> (query: String, agencyID: Int)? in + guard let query = noti.userInfo?["query"] as? String, + let agencyID = noti.userInfo?["agencyID"] as? Int else { return nil } + return (query, agencyID) + } + .bind(with: self) { owner, userInfo in + switch userInfo.query { case "OCR": - owner.coordinator?.move(to: .createOCRLedger(agencyID)) + owner.coordinator?.move(to: .createOCRLedger(userInfo.agencyID)) case "CreateLedger": - owner.coordinator?.move(to: .createManualLedger(agencyID)) + owner.coordinator?.move(to: .createManualLedger(userInfo.agencyID)) case "LedgerDetail": owner.coordinator?.move(to: .ledger) default: break