@@ -67,45 +67,66 @@ function useDeepLink() {
6767 const timerRef = useRef < number | null > ( null ) ;
6868
6969 return useCallback ( ( schemeUrl : string ) => {
70- const clear = ( ) => {
70+ const ua = navigator . userAgent || '' ;
71+ const isIOS = / i P h o n e | i P a d | i P o d / i. test ( ua ) ;
72+ const storeUrl = IOS_STORE_URL ; // 안드용은 아래 else 브랜치에서 처리
73+
74+ // 공통 이벤트/타이머 정리
75+ const clearAll = ( ) => {
7176 if ( timerRef . current ) {
7277 window . clearTimeout ( timerRef . current ) ;
7378 timerRef . current = null ;
7479 }
75- document . removeEventListener ( 'visibilitychange' , onVisChange ) ;
76- window . removeEventListener ( 'pagehide' , onPageHide ) ;
80+ document . removeEventListener ( 'visibilitychange' , onVis ) ;
81+ window . removeEventListener ( 'pagehide' , onHide ) ;
7782 window . removeEventListener ( 'blur' , onBlur ) ;
7883 } ;
79-
80- const onVisChange = ( ) => {
81- if ( document . hidden ) clear ( ) ;
82- } ;
83- const onPageHide = ( ) => clear ( ) ;
84- const onBlur = ( ) => clear ( ) ;
85-
86- const ua = navigator . userAgent || '' ;
87- const isIOS = / i P h o n e | i P a d | i P o d / i. test ( ua ) ;
88- const storeUrl = isIOS ? IOS_STORE_URL : ANDROID_STORE_URL ;
89-
90- clear ( ) ; // 혹시 이전 타이머 남아있으면 초기화
91-
92- document . addEventListener ( 'visibilitychange' , onVisChange ) ;
93- window . addEventListener ( 'pagehide' , onPageHide ) ;
84+ const onVis = ( ) => document . hidden && clearAll ( ) ;
85+ const onHide = ( ) => clearAll ( ) ;
86+ const onBlur = ( ) => clearAll ( ) ;
87+
88+ // iOS: 새 창 핸들 준비(동일 클릭 제스처 내)
89+ // 앱이 뜨면 이 창은 사용자가 돌아오지 않으므로 타이머에서만 사용.
90+ let storeWin : Window | null = null ;
91+ if ( isIOS ) {
92+ storeWin = window . open ( '' , '_blank' ) ; // 팝업 차단 회피(사용자 제스처 내에서만 허용)
93+ }
94+
95+ clearAll ( ) ;
96+ document . addEventListener ( 'visibilitychange' , onVis ) ;
97+ window . addEventListener ( 'pagehide' , onHide ) ;
9498 window . addEventListener ( 'blur' , onBlur ) ;
9599
96100 const start = Date . now ( ) ;
97101
98- window . location . href = schemeUrl ;
99-
100- const fallbackDelay = isIOS ? 1200 : 800 ;
101-
102- timerRef . current = window . setTimeout ( ( ) => {
103- const elapsed = Date . now ( ) - start ;
104- if ( elapsed < 2500 ) {
105- window . location . replace ( storeUrl ) ;
106- }
107- clear ( ) ;
108- } , fallbackDelay ) ;
102+ if ( isIOS ) {
103+ // 1) 커스텀 스킴 시도 (앱 설치되어 있으면 전환, 아니면 iOS가 경고를 띄울 수 있음)
104+ window . location . href = schemeUrl ;
105+
106+ // 2) 일정 시간 내 전환 없으면 스토어로 폴백(열어둔 탭/창으로 이동)
107+ timerRef . current = window . setTimeout ( ( ) => {
108+ const elapsed = Date . now ( ) - start ;
109+ if ( elapsed < 2500 ) {
110+ if ( storeWin ) {
111+ // App Store 직접 열기(인터스티셜 없이): itms-apps://
112+ storeWin . location . href = 'itms-apps://itunes.apple.com/app/id6749781762' ;
113+ } else {
114+ window . location . replace ( storeUrl ) ;
115+ }
116+ }
117+ clearAll ( ) ;
118+ } , 1200 ) ;
119+ } else {
120+ // Android/기타: 기존 로직 유지 (경고 이슈 거의 없음)
121+ window . location . href = schemeUrl ;
122+ timerRef . current = window . setTimeout ( ( ) => {
123+ const elapsed = Date . now ( ) - start ;
124+ if ( elapsed < 2500 ) {
125+ window . location . replace ( ANDROID_STORE_URL ) ;
126+ }
127+ clearAll ( ) ;
128+ } , 800 ) ;
129+ }
109130 } , [ ] ) ;
110131}
111132
0 commit comments