라우트 결정 핸들러(Route Decision Handlers) 개요
Hotwire Native iOS 1.2에서 소개된 라우트 결정 핸들러는 앱 내 URL 내비게이션을 가로채고, 특정 조건에 따라 다른 동작을 수행하도록 합니다. 이는 RouteDecisionHandler
프로토콜을 구현하여 이루어지며, 다음 세 가지 필수 함수를 포함합니다:
* name
: 핸들러의 고유 이름 (문자열).
* matches(proposal:configuration:)
: 주어진 내비게이션 제안(proposal)이 이 핸들러에 의해 처리되어야 하는지 여부를 결정합니다. true
를 반환하면 handle
함수가 호출됩니다.
* handle(proposal:completionHandler:)
: 내비게이션을 실제로 처리하는 로직을 포함합니다. RouterDecision.navigate
또는 RouterDecision.cancel
을 반환하여 내비게이션을 진행하거나 취소할 수 있습니다.
내장 라우트 결정 핸들러
Hotwire Native는 기본적으로 세 가지 내장 핸들러를 제공하며, 특정 순서대로 실행됩니다:
* AppNavigationRouteDecisionHandler
: 현재 앱의 호스트와 동일한 도메인 내의 URL 내비게이션을 처리합니다. 주로 Hotwire Turbo를 통한 인앱 내비게이션에 사용됩니다.
* SafariViewControllerRouteDecisionHandler
: HTTP 또는 HTTPS 스킴을 사용하지만 앱의 호스트와 다른 외부 도메인 URL을 처리합니다. 이 경우 내비게이션을 취소하고 SFSafariViewController
를 사용하여 외부 웹사이트를 표시합니다.
* SystemNavigationRouteDecisionHandler
: 앱이 직접 처리할 수 없는 모든 외부 URL 스킴(예: sms:
, mailto:
)을 시스템의 UIApplication.shared.open(url:)
메서드를 통해 처리합니다.
커스텀 라우트 결정 핸들러 구현 및 개선
본 세션에서는 SystemNavigationRouteDecisionHandler
의 동작을 개선하기 위해 커스텀 핸들러인 DemoSystemNavigationHandler
를 구현하는 과정을 시연합니다. 특히, mailto:
링크와 같이 장치에 해당 클라이언트 앱(메일 앱)이 설치되어 있지 않을 경우 발생하는 사용자 경험 문제를 해결하는 데 초점을 맞춥니다.
문제점: mailto:
링크 처리
기본 SystemNavigationRouteDecisionHandler
는 UIApplication.shared.open(url:)
을 호출하여 mailto:
링크를 처리합니다. 그러나 장치에 메일 클라이언트가 설치되어 있지 않으면, 이 호출은 실패하고 사용자에게는 아무런 피드백 없이 동작이 멈춘 것처럼 보입니다.
해결책: 사용자 알림 제공
커스텀 핸들러에서는 UIApplication.shared.open(URL:options:completionHandler:)
메서드의 completionHandler
를 활용하여 URL 열기 시도 성공 여부를 확인합니다. 만약 실패할 경우, 사용자에게 ‘장치에서 이 URL을 열 수 없습니다’라는 내용의 UIAlertController
를 표시하여 명확한 피드백을 제공합니다. 이 방법은 canOpenURL
메서드의 Info.plist
제한(최대 50개 스킴)을 우회하며, 더 유연하고 안정적인 에러 처리를 가능하게 합니다.
웹뷰 정책 결정 핸들러(WebView Policy Decision Handlers)
라우트 결정 핸들러와 유사하게, WebViewPolicyDecisionHandlers
는 웹뷰 내의 특정 내비게이션 액션(예: 페이지 새로고침, 새 창 열기)을 가로채고 커스텀 동작을 수행하는 데 사용됩니다. reload
, new window
, external navigation
, link activated
와 같은 내장 핸들러가 있으며, 이는 웹뷰의 동작을 더욱 세밀하게 제어할 수 있도록 합니다.