Skip to content

[Feat] #821 - universal link #825

Open
juri123123 wants to merge 9 commits intodevelopfrom
feat/#821-universal-link
Open

[Feat] #821 - universal link #825
juri123123 wants to merge 9 commits intodevelopfrom
feat/#821-universal-link

Conversation

@juri123123
Copy link
Copy Markdown
Contributor

🌴 PR 요약

외부 링크(문자, 카카오톡 등)에서 SOPT 앱으로 직접 진입할 수 있도록 Universal Links를 구현했습니다.

🌱 작업한 브랜치

🌱 PR Point

  1. Universal Links 설정
  • Associated Domains 추가
  1. SceneDelegate 딥링크 핸들러 구현
  • scene(_:continue:) 메서드 추가
  1. ApplicationCoordinator 개선
  • universalWebLink 옵션 처리 추가
  • NotificationHandler를 통한 웹링크 전달
  1. NotificationHandler 활용
  • TabBar 생성 완료 후 대기 중이던 링크 처리하는 sendNotificationIfNeeded() 메서드 사용
  • 웹링크/딥링크 통합 관리

📌 참고 사항

서버 설정 필요
dev/prod 도메인 둘 다 AASA 파일 배포를 부탁드린 상태입니다.

📮 관련 이슈

@juri123123 juri123123 self-assigned this Feb 1, 2026
@juri123123 juri123123 added Feat 새로운 기능 구현 주리🫐 labels Feb 1, 2026
@juri123123 juri123123 linked an issue Feb 1, 2026 that may be closed by this pull request
1 task
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 1, 2026

Walkthrough

SceneDelegate에 유니버설 링크 진입점을 추가하고, 해당 링크를 .universalWebLink로 변환해 ApplicationCoordinator로 전달하도록 라우팅을 확장했습니다. 앱 및 데모 타겟에 Associated Domains entitlements가 추가되었습니다.

Changes

Cohort / File(s) Summary
Entitlements (Associated Domains)
SOPT-iOS/Projects/Demo/SOPT-iOS-Demo.entitlements, SOPT-iOS/Projects/SOPT-iOS/SOPT-iOS.entitlements
com.apple.developer.associated-domains 항목 추가 (applinks:... 도메인 배열 포함).
SceneDelegate (진입점 및 흐름 제어)
SOPT-iOS/Projects/Demo/Sources/Application/SceneDelegate.swift, SOPT-iOS/Projects/SOPT-iOS/Sources/Application/SceneDelegate.swift
willConnectTo에서 connectionOptions.userActivities 존재 시 유니버설 링크 처리로 분기하도록 변경 및 scene(_:continue:) 추가.
SceneDelegate 확장 (URL 처리)
SOPT-iOS/Projects/Demo/Sources/Application/SceneDelegate+HandleURL.swift, SOPT-iOS/Projects/SOPT-iOS/Sources/Application/SceneDelegate+HandleURL.swift
handleUniversalLink(_:), handleUniversalLinkWithUserActivity(_:) 추가: NSUserActivity에서 webpageURL 추출 후 .universalWebLink(url:)로 전달하거나 실패 시 앱 시작 처리.
DeepLink 옵션
SOPT-iOS/Projects/Features/BaseFeatureDependency/Sources/Coordinator/Options/DeepLinkOptions.swift
DeepLinkOption.universalWebLink(url: String) 케이스 추가 및 url 프로퍼티 분기 확장.
ApplicationCoordinator / Notification flow
SOPT-iOS/Projects/Features/RootFeature/Sources/ApplicationCoordinator.swift, SOPT-iOS/Projects/Features/RootFeature/Sources/NotificationHelpers/NotificationHandler.swift
.universalWebLink 처리 경로 추가: notificationHandler.receive(webLink:)로 전달, webLink 바인딩에 .dropFirst() 적용, tabBarController 존재 여부로 처리 조건 조정, sendNotificationIfNeeded() 추가(NotificationHandler에 새 공개 메서드).

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant Scene as SceneDelegate
    participant Coordinator as ApplicationCoordinator
    participant Notifier as NotificationHandler
    participant TabBar as TabBarController

    User->>Scene: Universal link 클릭 (NSUserActivity)
    Scene->>Scene: scene(_:continue:) / willConnectTo 검사
    Scene->>Scene: webpageURL 추출
    Scene->>Coordinator: start(with: .universalWebLink(url))
    Coordinator->>Notifier: receive(webLink: url)
    Coordinator->>Notifier: sendNotificationIfNeeded()
    Notifier->>TabBar: webLink 재전송
    TabBar->>TabBar: 내비게이션 수행
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • hye0njuoo
  • dlwogus0128
  • yungu0010

Poem

🐰 유리길 따라 폴짝폴짝,
웹의 길이 앱에 닿으면,
도메인 달고 문을 열고,
알림 한 번 더 살랑살랑,
화면은 따라오네, 당근 들고 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed PR 설명은 유니버설 링크 구현의 목적, 구체적인 작업 내용, 설정 변경사항 등을 포함하고 있습니다.
Linked Issues check ✅ Passed PR은 유니버설 링크 구현 요구사항을 모두 충족합니다: Associated Domains 추가, SceneDelegate 핸들러 구현, ApplicationCoordinator 개선, NotificationHandler 활용이 모두 포함되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 유니버설 링크 구현 범위 내에 있으며, 관련 없는 변경사항은 없습니다.
Title check ✅ Passed PR 제목 '[Feat] #821 - universal link'는 PR의 주요 변경사항인 유니버설 링크 기능 구현을 명확하게 요약하고 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#821-universal-link

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@SOPT-iOS/Projects/Demo/Sources/Application/SceneDelegate.swift`:
- Around line 48-59: The app currently handles universal links only in
scene(_:continue:) and misses cold-start links passed via
scene(_:willConnectTo:options:); update scene(_:willConnectTo:options:) to
inspect connectionOptions.userActivities for an NSUserActivity with activityType
== NSUserActivityTypeBrowsingWeb, extract its webpageURL, and call
handleUniversalLink(_:) with the URL.absoluteString (keeping the existing guard
logic used in scene(_:continue:)); reference scene(_:willConnectTo:options:),
connectionOptions.userActivities, NSUserActivityTypeBrowsingWeb, and
handleUniversalLink(_:) when making the change.

In `@SOPT-iOS/Projects/Features/RootFeature/Sources/ApplicationCoordinator.swift`:
- Around line 108-118: The deepLink and notificationLinkError subscriptions use
childCoordinators.contains(where: { $0 is DefaultTabBarCoordinator }) which
always returns false because DefaultTabBarCoordinator is never appended in
runTabBarFlow; update those subscriptions to use the same existence check as
webLink (self.tabBarController != nil) or alternatively ensure runTabBarFlow
appends the DefaultTabBarCoordinator to childCoordinators; adjust the filters
for deepLink and notificationLinkError to use self.tabBarController != nil (or
append DefaultTabBarCoordinator in runTabBarFlow) so handleDeepLink and
handleNotificationLinkError can actually be invoked.

In `@SOPT-iOS/Projects/SOPT-iOS/SOPT-iOS.entitlements`:
- Around line 11-14: The entitlements file references $(APPLINK) but APPLINK is
not defined anywhere, and the xcconfig files referenced by Configurations.swift
(xcconfigs/Base/Projects/Project-{Development,Test,QA,PROD}.xcconfig) are
missing; to fix, add or restore those xcconfig files and define APPLINK in each
configuration (Development, Test, QA, PROD) or alternatively set the APPLINK
build setting via your Tuist project manifest so the SOPT-iOS.entitlements key
com.apple.developer.associated-domains resolves correctly; ensure
Configurations.swift points to the actual xcconfig paths or update Tuist to
inject the APPLINK value for each build configuration.
🧹 Nitpick comments (1)
SOPT-iOS/Projects/Features/RootFeature/Sources/NotificationHelpers/NotificationHandler.swift (1)

111-118: 중복 발행 방지 로직을 고려해주세요.
sendNotificationIfNeeded()가 여러 번 호출되면 동일 링크가 재발행되어 중복 네비게이션이 발생할 수 있습니다. 한 번만 발행되도록 플래그 가드를 두는 방식을 고려해주세요.

♻️ 예시 수정안
 public final class NotificationHandler: NSObject, UNUserNotificationCenterDelegate {
     
     public let deepLink = CurrentValueSubject<DeepLinkComponentsExecutable?, Never>(nil)
     public let webLink = CurrentValueSubject<String?, Never>(nil)
     public let notificationLinkError = CurrentValueSubject<NotificationLinkError?, Never>(nil)
+    private var didSendPendingLinks = false
@@
     public func sendNotificationIfNeeded() {
+        guard !didSendPendingLinks else { return }
+        didSendPendingLinks = true
         if let wLink = self.webLink.value {
             self.webLink.send(wLink)
         }
         
         if let dLink = self.deepLink.value {
             self.deepLink.send(dLink)
         }
     }
 }

알림 링크 타입에 따라 필터링 조건 분리

- DeepLink는 coordinator를 통해 라우팅되므로
  DefaultTabBarCoordinator 준비 여부로 필터링
- NotificationLinkError, webLink는 viewController에 직접 접근이 필요해
  tabBarController 존재 여부로 필터링
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@SOPT-iOS/Projects/Features/RootFeature/Sources/ApplicationCoordinator.swift`:
- Around line 108-115: The subscription on notificationHandler.webLink is
dropping the first real URL because dropFirst() is applied after compactMap;
move dropFirst() to before compactMap (i.e., call .dropFirst() directly on
webLink) or remove dropFirst() entirely so that the first non-nil emission from
CurrentValueSubject<String?, Never>(nil) is not discarded; update the chain
around notificationHandler.webLink, .dropFirst(), .compactMap { $0 },
.receive(on:), .filter { self.tabBarController != nil }, .sink { [weak self] url
in ... } accordingly.

In `@SOPT-iOS/Projects/SOPT-iOS/Sources/Application/SceneDelegate.swift`:
- Around line 40-44: The current flow calls
handleUniversalLinkWithUserAcitivity(userActivity) for any userActivity, but if
that method early-returns when the activity.type !=
NSUserActivityTypeBrowsingWeb it never falls back to starting the app; update
the logic so non-browsing activities still start the app: either (A) in the
SceneDelegate where you check connectionOptions.userActivities.first, inspect
userActivity.activityType and only call handleUniversalLinkWithUserAcitivity if
activityType == NSUserActivityTypeBrowsingWeb and otherwise call
self.appCoordinator.start(), or (B) modify handleUniversalLinkWithUserAcitivity
to call self.appCoordinator.start() when its guard for
NSUserActivityTypeBrowsingWeb fails; reference
handleUniversalLinkWithUserAcitivity(userActivity),
NSUserActivityTypeBrowsingWeb, and appCoordinator.start().

Comment on lines +40 to +44
if let userActivity = connectionOptions.userActivities.first {
handleUniversalLinkWithUserAcitivity(userActivity)
} else {
self.appCoordinator.start()
}
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "SceneDelegate.swift" -type f

Repository: sopt-makers/SOPT-iOS

Length of output: 367


🏁 Script executed:

cat -n SOPT-iOS/Projects/SOPT-iOS/Sources/Application/SceneDelegate.swift | head -80

Repository: sopt-makers/SOPT-iOS

Length of output: 2756


🏁 Script executed:

rg "handleUniversalLinkWithUserAcitivity|handleUniversalLink" -B 2 -A 10

Repository: sopt-makers/SOPT-iOS

Length of output: 8318


유니버설 링크가 아닌 userActivity에서 앱 시작이 누락됩니다.

userActivity가 존재하지만 웹 브라우징 activity가 아니면 handleUniversalLinkWithUserAcitivity() 메서드가 early return되어 appCoordinator.start()가 호출되지 않습니다. NSUserActivityTypeBrowsingWeb 확인에 실패한 경우 기본 start로 폴백해야 합니다.

수정 제안
        if let userActivity = connectionOptions.userActivities.first {
            handleUniversalLinkWithUserAcitivity(userActivity)
        } else {
            self.appCoordinator.start()
        }

또는 handleUniversalLinkWithUserAcitivity 메서드 내에서 guard 실패 시 self.appCoordinator.start() 호출:

    func handleUniversalLinkWithUserAcitivity(_ userActivity: NSUserActivity) {
        guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
              let incomingURL = userActivity.webpageURL else {
            print("❌ Not a universal link")
+           self.appCoordinator.start()
            return
        }

        handleUniversalLink(incomingURL.absoluteString)
    }
🤖 Prompt for AI Agents
In `@SOPT-iOS/Projects/SOPT-iOS/Sources/Application/SceneDelegate.swift` around
lines 40 - 44, The current flow calls
handleUniversalLinkWithUserAcitivity(userActivity) for any userActivity, but if
that method early-returns when the activity.type !=
NSUserActivityTypeBrowsingWeb it never falls back to starting the app; update
the logic so non-browsing activities still start the app: either (A) in the
SceneDelegate where you check connectionOptions.userActivities.first, inspect
userActivity.activityType and only call handleUniversalLinkWithUserAcitivity if
activityType == NSUserActivityTypeBrowsingWeb and otherwise call
self.appCoordinator.start(), or (B) modify handleUniversalLinkWithUserAcitivity
to call self.appCoordinator.start() when its guard for
NSUserActivityTypeBrowsingWeb fails; reference
handleUniversalLinkWithUserAcitivity(userActivity),
NSUserActivityTypeBrowsingWeb, and appCoordinator.start().

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleUniversalLinkWithUserActivity 메서드 내에서 확인하고 있는 것으로 보임

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg "handleUniversalLinkWithUserActivity|handleUniversalLinkWithUserAcitivity|appCoordinator.start" SOPT-iOS/Projects/SOPT-iOS/Sources/Application/SceneDelegate+HandleURL.swift -n -A 5 -B 2

Length of output: 682


@yungu0010, 맞습니다! 확인 결과 handleUniversalLinkWithUserActivity 메서드 내부(Line 72–76)에서 guard 실패 시 appCoordinator.start()를 호출하는 폴백이 이미 구현되어 있습니다:

func handleUniversalLinkWithUserActivity(_ userActivity: NSUserActivity) {
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
          let incomingURL = userActivity.webpageURL else {
        print("❌ Not a universal link")
        appCoordinator.start()  // ✅ 폴백 처리됨
        return
    }
    handleUniversalLink(incomingURL.absoluteString)
}

제가 처음에 메서드 내부 구현을 잘못 판단했습니다. 지적해주셔서 감사합니다!


🧠 Learnings used
Learnt from: dlwogus0128
Repo: sopt-makers/SOPT-iOS PR: 699
File: SOPT-iOS/Projects/Features/RootFeature/Sources/ApplicationCoordinator.swift:576-581
Timestamp: 2025-09-23T04:48:57.229Z
Learning: In SOPT-iOS coordinator refactoring: Legacy coordinators require addDependency() calls for proper lifecycle management, but the new coordinator architecture handles dependency management differently and does not require explicit addDependency() calls.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
SOPT-iOS/Projects/Features/RootFeature/Sources/ApplicationCoordinator.swift (1)

97-106: ⚠️ Potential issue | 🔴 Critical

deepLink 필터가 여전히 DefaultTabBarCoordinator 체크를 사용하고 있어 항상 false를 반환합니다.

webLink (Line 113)와 notificationLinkError (Line 124)는 self.tabBarController != nil로 업데이트되었지만, deepLink는 여전히 self.childCoordinators.contains(where: { $0 is DefaultTabBarCoordinator })를 사용합니다.

이전 리뷰에서 지적된 대로 TabBarCoordinatorchildCoordinators에 추가되지 않기 때문에 이 필터는 항상 false를 반환하여 handleDeepLink가 절대 실행되지 않습니다.

🐛 수정 제안
         self.notificationHandler.deepLink
             .compactMap { $0 }
             .receive(on: DispatchQueue.main)
             .filter { _ in
-                self.childCoordinators.contains(where: { $0 is DefaultTabBarCoordinator })
+                self.tabBarController != nil
             }
             .sink { [weak self] deepLinkComponent in
                 self?.handleDeepLink(deepLink: deepLinkComponent)
                 self?.notificationHandler.clearNotificationRecord()
             }.store(in: cancelBag)
🤖 Fix all issues with AI agents
In `@SOPT-iOS/Projects/Demo/Sources/Application/SceneDelegate`+HandleURL.swift:
- Line 71: Rename the misspelled method handleUniversalLinkWithUserAcitivity to
handleUniversalLinkWithUserActivity and update all call sites accordingly;
specifically rename the method declaration in SceneDelegate+HandleURL (the
function currently named handleUniversalLinkWithUserAcitivity) and change every
invocation in SceneDelegate files that call handleUniversalLinkWithUserAcitivity
to call handleUniversalLinkWithUserActivity so signatures match.

appCoordinator.start(with: .universalWebLink(url: url))
}

func handleUniversalLinkWithUserAcitivity(_ userActivity: NSUserActivity) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

rg -n "handleUniversalLinkWithUserAcitivity" --type swift

Repository: sopt-makers/SOPT-iOS

Length of output: 895


🏁 Script executed:

rg -n "handleUniversalLinkWithUserActivity" --type swift

Repository: sopt-makers/SOPT-iOS

Length of output: 46


메서드 이름의 오타를 수정해야 합니다.

handleUniversalLinkWithUserAcitivityhandleUniversalLinkWithUserActivity ("Acitivity" → "Activity")

다음 위치들에서 모두 수정이 필요합니다:

  • SOPT-iOS/Projects/SOPT-iOS/Sources/Application/SceneDelegate+HandleURL.swift:71 (메서드 정의)
  • SOPT-iOS/Projects/SOPT-iOS/Sources/Application/SceneDelegate.swift:41, 55 (호출 부분)
  • SOPT-iOS/Projects/Demo/Sources/Application/SceneDelegate+HandleURL.swift:71 (메서드 정의)
  • SOPT-iOS/Projects/Demo/Sources/Application/SceneDelegate.swift:42, 56 (호출 부분)
🤖 Prompt for AI Agents
In `@SOPT-iOS/Projects/Demo/Sources/Application/SceneDelegate`+HandleURL.swift at
line 71, Rename the misspelled method handleUniversalLinkWithUserAcitivity to
handleUniversalLinkWithUserActivity and update all call sites accordingly;
specifically rename the method declaration in SceneDelegate+HandleURL (the
function currently named handleUniversalLinkWithUserAcitivity) and change every
invocation in SceneDelegate files that call handleUniversalLinkWithUserAcitivity
to call handleUniversalLinkWithUserActivity so signatures match.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@SOPT-iOS/Projects/SOPT-iOS/Sources/Application/SceneDelegate`+HandleURL.swift:
- Around line 71-80: The guard failure currently always calls
appCoordinator.start(), which will restart the coordinator when
handleUniversalLinkWithUserActivity(_:) is invoked from scene(_:continue:),
causing unwanted navigation; change handleUniversalLinkWithUserActivity(_:) to
accept a caller-context flag (e.g., isInitialLaunch: Bool = false) or add an
explicit parameter (keep function name handleUniversalLinkWithUserActivity) and
only call appCoordinator.start() when isInitialLaunch is true (the
scene(_:willConnectTo:options:) caller should pass true, scene(_:continue:)
should pass false); also update both callers (scene(_:willConnectTo:options:)
and scene(_:continue:)) to pass the appropriate flag so scene(_:continue:)
returns without restarting the coordinator on guard failure.

Comment on lines +71 to +80
func handleUniversalLinkWithUserActivity(_ userActivity: NSUserActivity) {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL else {
print("❌ Not a universal link")
appCoordinator.start()
return
}

handleUniversalLink(incomingURL.absoluteString)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

rg -n -B5 -A5 'handleUniversalLinkWithUserActivity' --type swift

Repository: sopt-makers/SOPT-iOS

Length of output: 6922


scene(_:continue:)에서 호출될 때 guard 실패 처리 개선 필요

이 함수는 앱 시작 시 scene(_:willConnectTo:options:)과 앱이 이미 실행 중일 때 scene(_:continue:)에서 호출됩니다. 현재 guard 실패 시 두 경로 모두에서 appCoordinator.start()를 호출하고 있으므로, scene(_:continue:)에서 호출되는 경우 이미 활성화된 coordinator를 재시작하게 되어 예상치 못한 네비게이션 상태 변경이나 시각적 결함을 유발할 수 있습니다.

guard 실패 시 호출 컨텍스트에 따라 다르게 처리하거나, 최소한 scene(_:continue:)에서는 coordinator를 재시작하지 않고 단순 반환하도록 개선하세요.

🤖 Prompt for AI Agents
In `@SOPT-iOS/Projects/SOPT-iOS/Sources/Application/SceneDelegate`+HandleURL.swift
around lines 71 - 80, The guard failure currently always calls
appCoordinator.start(), which will restart the coordinator when
handleUniversalLinkWithUserActivity(_:) is invoked from scene(_:continue:),
causing unwanted navigation; change handleUniversalLinkWithUserActivity(_:) to
accept a caller-context flag (e.g., isInitialLaunch: Bool = false) or add an
explicit parameter (keep function name handleUniversalLinkWithUserActivity) and
only call appCoordinator.start() when isInitialLaunch is true (the
scene(_:willConnectTo:options:) caller should pass true, scene(_:continue:)
should pass false); also update both callers (scene(_:willConnectTo:options:)
and scene(_:continue:)) to pass the appropriate flag so scene(_:continue:)
returns without restarting the coordinator on guard failure.

Copy link
Copy Markdown
Member

@yungu0010 yungu0010 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다! 몇 가지 질문 남겼습니다!

SceneDelegate나 새로 추가된 함수에 대해 주석을 달아두는건 어떨까요? 추후 유니버셜 링크 작업을 유지보수하는 데 도움이 될 것 같아요~~

}.store(in: cancelBag)

self.notificationHandler.webLink
.dropFirst()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dropFirst를 추가해준 이유가 궁금합니다!
기존 웹링크 알림 로직도 정상적으로 동작하나요?

self.notificationLinkError.send(nil)
}

public func sendNotificationIfNeeded() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 함수가 왜 필요한지 궁금합니다! handleWebLinkhandleDeepLink를 사용하면 안되나요 ? ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

유니버설 링크의 경우 앱이 초기화 되기 전에 (Coordinator, TabBarCon..등) 들어와서 NotificationHandelr에 저장되고 있는데, 들어온 당시에는 bindNotification이 처리되기 전이라서 이벤트를 수신하지 못하고 있었습니다 ! 따라서 모두 bind한 뒤에 만약 저장된 웹링크가 있다면 재방출해줄 수 있도록 처리했습니다.

handleWebLink와 handleDeepLink는 파싱하는 역할을 해주고 있어서 새로운 함수를 통해 재방출을 구현했습니다.

Comment on lines +40 to +44
if let userActivity = connectionOptions.userActivities.first {
handleUniversalLinkWithUserAcitivity(userActivity)
} else {
self.appCoordinator.start()
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleUniversalLinkWithUserActivity 메서드 내에서 확인하고 있는 것으로 보임

@yungu0010 yungu0010 changed the title [Feat] #821 universal link [Feat] #821 - universal link Mar 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feat 새로운 기능 구현 size/M 주리🫐

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 유니버셜 링크 작업

2 participants