이슈
flow
(safari) 앱이 있음
> ~앱으로 이동하시겠습니까? confirm 이 뜸
> 2.5초 전 누르면 즉시 앱 실행 (앱으로 이동했기때문에 더이상 js가 타지않아 마켓 실행되지않음)
> 2.5초 후 누르면 > 앱 실행 > 마켓으로 이동
(confirm이 뜬 상태라 js는 이미 실행되었어야하는데 막힌상태. confirm닫자마자 js 차례로 실행됨. 앱이 있는데도 마켓으로 실행이 됨)
아래 소스는 기존 소스로 javascript 앱 마켓이동, 앱 다운로드 유도 등으로 인터넷에 치면 자주 보이는 소스이다.
ios 같은 경우에는 앱이 있는지 없는지에 대한 callback이 없으므로 유저의 앱의 다운로드 유무에 대해 알수가 없다. 따라서 앱을 실행하고 일정시간 이후에 그 페이지에 계속 남아있다면 앱이 없는것으로 간주하고 앱 스토어 주소로 이동하게 되어있다.
그런데 브라우저 별로 앱 주소가 들어오면 실행하는 방식이 다른데, safari에서는 "~~을 여시겠습니까?" 라는 confirm이 뜬다. 여기서 이슈는 앱이 있는 경우에 바로 확인버튼을 누르지 않고 setTimeout을 설정해놓은 일정시간이후에 confirm의 확인버튼을 누르게 되면 앱이 열린 다음 마켓으로 강제로 이동하게 되는 것이 이슈이다.
const openAppStore = () => { // 앱 다운로드 유도 배너 const userAgent = navigator.userAgent; const visiteTm = (new Date()).getTime(); if (userAgent.match(".*Android.*")) { if (userAgent.match(/Chrome/)) { setTimeout(function() { location.href = "intent://#Intent;scheme=;end"; //안드로이드 마켓 주소 }, 1000); } else { // 크롬 이외의 브라우저들 setTimeout(function() { if ((new Date()).getTime() - visiteTm < 2000) { location.href = "market://details?id=com"; //안드로이드 마켓 주소 } }, 500); var iframe = document.createElement('iframe'); if (iframe) { iframe.style.visibility = 'hidden'; iframe.src = 'intent://#Intent;scheme=;end'; document.body.appendChild(iframe); document.body.removeChild(iframe); // back 호출시 캐싱될 수 있으므로 제거 } } } else if (userAgent.match(".*iPhone.*") || userAgent.match(".*iPad.*")){ //아이폰 setTimeout( function () { if (( new Date() ).getTime() - visiteTm < 3000) { location.href = "https://apps.apple.com/app/id"; //ios 앱스토어 주소 } }, 2500); setTimeout( function () { // 앱실행 location.href = "앱주소://"; }, 0); } }
해결방법
아래 소스에서 포인트는 focus 이벤트를 이용한 것이다. confirm을 껐을때 앱으로 이동했느냐 아직 web상에 머물러있냐로 판별하여 web상에 머물러있다면 앱이 없다고 생각하고 앱스토어로 이동하는 이벤트를 실행한다.
flow
> 앱으로 이동함수 실행
> 앱으로 이동하시겠습니까? confirm
앱이 있는경우 > 이동되고 끝
앱이 없는경우 > confirm 이 닫히고 window에 focus 되므로 앱스토어로 이동하는 이벤트 실행
const openAppStore = function() { //딥링크 기본 주소 설정 (홈) deepLink = deepLink ? deepLink : appScheme + "main?mainTab=0"; const userAgent = navigator.userAgent; /* 안드로이드 */ if (userAgent.match(".*Android.*")) { const parsingDeepLink = deepLink.split(appScheme); //안드로이드 마켓주소 location.href = "intent://딥링크#Intent;scheme="; } /* IOS */ else if (userAgent.match(".*iPhone.*") || userAgent.match(".*iPad.*")) { var marketLink = ""; //아이폰 앱스토어 주소 marketLink = "https://apps.apple.com/kr/app/id"; // 앱 이동 function redirectToApp() { window.location.href = deepLink; } // 마켓 이동 function redirectToMarket(_type) { setTimeout( function () { window.location.href = marketLink; }, _type === "CATCH" ? 200 : 900 ); } // 앱 이동 안되고 알럿꺼서 다시 FOCUS 될때 (==> 앱이 없다고 판단 가능하므로 마켓으로 이동시킴) window.addEventListener("focus", redirectToMarket, {once: true}); // 앱 이동으로 실행 try { redirectToApp(); } catch (e) { // 이건 거의 안타지만 혹시 몰라서 방어코드로 추가 redirectToMarket("CATCH"); } } }
반응형
'Issues > Mobile(Web&App)' 카테고리의 다른 글
[html & ios] 전화번호가 들어있는 span태그로 감싼 텍스트인데 전화가 되고 css가 이상할때 (0) | 2021.12.29 |
---|---|
[IOS & javascript] ios 이모티콘 키패드 height 조정하기 (emoji keypad window resize) (0) | 2021.12.08 |
[CSS& Mobile] 모바일 브라우저 주소창과 바텀시트 고정시키기 (0) | 2021.12.07 |
[IOS & javascript] new Date() invalid date 오류! (0) | 2021.12.03 |