Skip to content

[IDLE-447] 유저가 알림확인창에서 내재된 액션을 수행할 수 있다 #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ open class BaseCoordinator: Coordinator {

open func start() { }

public func findChild<T: Coordinator>(coordinatorType: T.Type) -> T? {

for child in children {
if let target = child as? T {
return target
}
}
return nil
}

public func addChild(_ coordinator: Coordinator) {

children.append(coordinator)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// DeeplinkBundle.swift
// BaseFeature
//
// Created by choijunios on 10/17/24.
//

import Foundation

public struct DeeplinkBundle {
public let deeplinks: [DeeplinkExecutable]
public let userInfo: [AnyHashable: Any]?

public init(deeplinks: [DeeplinkExecutable], userInfo: [AnyHashable : Any]?) {
self.deeplinks = deeplinks
self.userInfo = userInfo
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import Foundation

public protocol DeeplinkTreeNode {

var name: String { get }
var component: DeepLinkPathComponent { get }
var children: [DeeplinkExecutable] { get }
var isDestination: Bool { get set }

func findChild(name: String) -> DeeplinkExecutable?
func findChild(component: DeepLinkPathComponent) -> DeeplinkExecutable?
}

public protocol DeeplinkExecutable: DeeplinkTreeNode {
Expand All @@ -23,8 +23,8 @@ public protocol DeeplinkExecutable: DeeplinkTreeNode {

public extension DeeplinkExecutable {

func findChild(name: String) -> DeeplinkExecutable? {
children.first(where: { $0.name == name })
func findChild(component: DeepLinkPathComponent) -> DeeplinkExecutable? {
children.first(where: { $0.component == component })
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// RemoteNotificationHelper.swift
// BaseFeature
//
// Created by choijunios on 10/17/24.
//

import Foundation
import Domain


import RxSwift

public protocol RemoteNotificationHelper {

var deeplinks: BehaviorSubject<DeeplinkBundle> { get }

/// 인앱에서 발생한 Notification을 처리합니다.
func handleNotificationInApp(detail: NotificationDetailVO)
}

public enum DeepLinkPathComponent {
case centerMainPage
case postApplicantPage
case splashPage
}

public enum PreDefinedDeeplinkPath: String {
case postApplicant = "APPLICANT"

public var outsideLinks: [DeepLinkPathComponent] {
switch self {
case .postApplicant:
[.centerMainPage, .postApplicantPage]
}
}

public var insideLinks: [DeepLinkPathComponent] {
switch self {
case .postApplicant:
[.postApplicantPage]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ public extension CenterMainPageCoordinator {
}

// MARK: SubPages
extension CenterMainPageCoordinator {
public extension CenterMainPageCoordinator {

public func presentPostApplicantPage(postId: String) {
func presentPostApplicantPage(postId: String) {

let viewModel = PostApplicantViewModel(postId: postId)
viewModel.createCellViewModel = { applicantVO in
Expand All @@ -175,7 +175,7 @@ extension CenterMainPageCoordinator {
router.push(module: viewController, animated: true)
}

public func presentPostEditPage(postId: String) {
func presentPostEditPage(postId: String) {
let viewModel = EditPostVM(id: postId)
viewModel.exitPage = { [weak self] in
self?.router.popModule(animated: true)
Expand All @@ -190,7 +190,7 @@ extension CenterMainPageCoordinator {
router.push(module: viewController, animated: true)
}

public func presentPostDetailPage(postId: String, postState: PostState) {
func presentPostDetailPage(postId: String, postState: PostState) {
let viewModel = PostDetailViewModel(postId: postId, postState: postState)

viewModel.presentApplicantPage = { [weak self] postId in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class NotificationCellViewModel {
// Injected
@Injected var cacheRepository: CacheRepository
@Injected var notificationsRepository: NotificationsRepository
@Injected var remoteNotificationHelper: RemoteNotificationHelper

// Navigation
var presentAlert: ((DefaultAlertObject) -> ())?
Expand Down Expand Up @@ -55,6 +56,21 @@ class NotificationCellViewModel {
}

// MARK: 클릭 이벤트

/// 딥링크 처리
cellClicked
.unretained(self)
.subscribe(onNext: { (obj, _) in

guard let notificationDetails = notificationVO.notificationDetails else { return }

obj.remoteNotificationHelper
.handleNotificationInApp(detail: notificationDetails)
})
.disposed(by: disposeBag)


/// 읽음 처리
let readRequestResult = cellClicked
.unretained(self)
.flatMap { (obj, _) in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import BaseFeature

class CenterMainPageDeeplink: DeeplinkExecutable {

var name: String = "CenterMainPage"
var component: DeepLinkPathComponent = .centerMainPage

var children: [DeeplinkExecutable] = [
PostApplicantDeeplink()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import BaseFeature

class PostApplicantDeeplink: DeeplinkExecutable {

var name: String = "PostApplicantPage"
var component: DeepLinkPathComponent = .postApplicantPage

var children: [DeeplinkExecutable] = []

Expand All @@ -20,15 +20,31 @@ class PostApplicantDeeplink: DeeplinkExecutable {
init() { }

func execute(with coordinator: any BaseFeature.Coordinator, userInfo: [AnyHashable : Any]?) -> Coordinator? {


var targetCoordinator: CenterMainPageCoordinator

guard let centerMainPageCoordinator = coordinator as? CenterMainPageCoordinator else {
if let centerMainCoordinator = coordinator as? CenterMainPageCoordinator {

// 상위 Coordinator가 CenterMainPageCoordinator일 경우

targetCoordinator = centerMainCoordinator

} else if let appCoordinator = coordinator as? AppCoordinator, let centerMainCoordinator = appCoordinator.findChild(coordinatorType: CenterMainPageCoordinator.self) {

// 상위 Coordinator가 AppCoordinator일 경우

targetCoordinator = centerMainCoordinator

} else {

return nil
}

guard let postId = userInfo?["postId"] as? String else { return nil }
guard let postId = userInfo?["jobPostingId"] as? String else { return nil }

centerMainPageCoordinator.presentPostApplicantPage(postId: postId)
targetCoordinator.presentPostApplicantPage(postId: postId)

return centerMainPageCoordinator
return targetCoordinator
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import BaseFeature

class SplashDeeplink: DeeplinkExecutable {

var name: String = "SplashPage"
var component: DeepLinkPathComponent = .splashPage

var children: [DeeplinkExecutable] = []

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,46 @@
import Foundation
import BaseFeature

enum DeeplinkParserError: Error {
enum DeeplinkParserError: LocalizedError {
case startPointNotFound
case rootNotFound
case childNotFound

var errorDescription: String? {
switch self {
case .startPointNotFound:
"딥링크 시작지점을 찾을 수 없음"
case .rootNotFound:
"답링크 루트를 찾을 수 없음"
case .childNotFound:
"자식 딥링크를 찾을 수 없음"
}
}
}

class DeeplinkParser {

func makeDeeplinkList(components: [String]) throws -> [DeeplinkExecutable] {
func makeDeeplinkList(components: [DeepLinkPathComponent], startFromRoot: Bool = true) throws -> [DeeplinkExecutable] {

var deeplinks: [DeeplinkExecutable] = []

for component in components {

if deeplinks.isEmpty {
let root = try findRoot(name: component)
deeplinks.append(root)

var start: DeeplinkExecutable!

if startFromRoot {
start = try findRoot(component: component)
} else {
start = try findStartPoint(component: component)
}

deeplinks.append(start)
continue
}

guard let parent = deeplinks.last, let child = parent.findChild(name: component) else {
guard let parent = deeplinks.last, let child = parent.findChild(component: component) else {
throw DeeplinkParserError.childNotFound
}

Expand All @@ -37,14 +57,25 @@ class DeeplinkParser {
return deeplinks
}

private func findRoot(name: String) throws -> DeeplinkExecutable {
switch name {
case "CenterMainPage":
private func findRoot(component: DeepLinkPathComponent) throws -> DeeplinkExecutable {
switch component {
case .centerMainPage:
return CenterMainPageDeeplink()
default:
throw DeeplinkParserError.rootNotFound
}
}

private func findStartPoint(component: DeepLinkPathComponent) throws -> DeeplinkExecutable {
switch component {
case .centerMainPage:
return CenterMainPageDeeplink()
case .postApplicantPage:
return PostApplicantDeeplink()
default:
throw DeeplinkParserError.startPointNotFound
}
}
}


This file was deleted.

Loading
Loading