티스토리 뷰

모바일 웹에서는 디바이스에 어떤 앱들이 설치되어 있는지 알 수 없다. 하지만 특정 앱의 앱링크(URL Scheme)를 알고 있다면(앱에서 정의가 되어있다면) 마치 앱의 설치를 알고 있는 것처럼 동작하도록 만들 수 있고, 원하는 정보들을 전달할 수 있다. 미리 정의된 앱링크를 호출하여 반응하는 앱이 있으면 해당 앱이 실행되고, 반응하는 앱이 없으면 일정 시간이 지난 후에 앱스토어 링크를 호출한다.


  1. 앱링크를 호출할 iframe을 생성한다. (미리 마크업을 해놓아도 상관없다.) iframe을 이용하는 이유는 앱링크가 유효하지 않을 경우 어떤 화면이 보일지 예상할 수 없기 때문이다. css 또는 스크립트를 이용하여 화면에 보이지 않도록 한다. iframe에 올바르지 않은 화면이 뜨더라도 사용자에게 보이지 않는다.

    $("body").append("<iframe id='____sorilink____'></iframe>");
    $("#____sorilink____").hide();
    


  2. 앱링크가 없을 경우를 대비한 앱스토어 링크를 setTimeout과 함께 정의한다.

    var openAt = new Date,
        uagentLow = navigator.userAgent.toLocaleLowerCase();
            
    setTimeout( function() {
                 
        if (new Date - openAt < 4000) { // 페이지가 열릴 때의 시간과 클릭 시점의 시간을 비교
            if (uagentLow.search("android") > -1) { // 안드로이드
                $("#____sorilink____").attr("src","market://details?id=com.soribada.android&hl=ko"); // 안드로이드 마켓 앱링크. "http"가 아닐 경우 iframe에서 호출
            } else if (uagentLow.search("iphone") > -1) { // 아이폰
                location.replace("https://itunes.apple.com/kr/app/solibada-myujig-mujehan-eum/id346528006?mt=8"); // "http"의 경우 스크립트로 호출
            }
        }
     
    }, 1000); // 앱링크를 실행한 후 1초간 반응이 없으면 마켓으로 이동
    


  3. iframe에서 앱링크를 호출한다. 앱링크에 반응하는 앱이 있다면 앱이 실행된다(이때 웹 페이지의 스크립트는 종료된다). 만약 앱이 실행되지 않는다면 일정 시간 후 setTimeout 함수가 실행되고 스토어로 이동한다.

    if(uagentLow.search("android") > -1){ // 안드로이드 $("#____sorilink____").attr("src", 'soribada30://applink?param=value'); // 안드로이드 앱링크 실행 else if(uagentLow.search("iphone") > -1){ // 아이폰 $("#____sorilink____").attr("src", 'soribada30://applink?param=value'); // 아이폰 앱링크 실행 }

    • 모바일 크롬 25버전 이상에서는 iframe에 embeding하는 방식이 동작하지 않는다. 크롬 25버전 이상에서는 intent URI를 이용한다.

      if(uagentLow.search("chrome") > -1 && navigator.appVersion.match(/Chrome\/\d+.\d+/)[0].split("/")[1] > 25){
          document.location.href = "intent://applink?param=value#Intent;scheme=soribada30;package=com.soribada.android;end";
      }else{
          $("#____sorilink____").attr("src", 'soribada30://applink?param=value');
      }
      
    • 안드로이드 킷캣 OS에서는 웹뷰도 크롬으로 바뀌었다. (버전은 30이다.) 하지만 웹뷰에서는 intent URI가 동작하지 않아서 분기가 필요하다.

      // 네이버, 다음에 대해서만 분기 처리. 그 외의 앱에서는 intent URI가 실행되지만 인식하지 못한다.
      if (uagentLow.indexOf("naver") != -1 || uagentLow.indexOf("daum") != -1) { 
          $("#____sorilink____").attr("src", 'soribada30://applink?param=value');
      } else {
          document.location.href = "intent://applink?param=value#Intent;scheme=soribada30;package=com.soribada.android;end";
      }
      


  4. 코드 정리를 하면 아래와 같다.

    var openAt = new Date, uagentLow = navigator.userAgent.toLocaleLowerCase(), chrome25, kitkatWebview; $("body").append("<iframe id='____sorilink____'></iframe>"); $("#____sorilink____").hide(); setTimeout( function() { if (new Date - openAt < 4000) { if (uagentLow.search("android") > -1) { $("#____sorilink____").attr("src","market://details?id=com.soribada.android&hl=ko"); } else if (uagentLow.search("iphone") > -1) { location.replace("https://itunes.apple.com/kr/app/solibada-myujig-mujehan-eum/id346528006?mt=8"); } } }, 1000); if(uagentLow.search("android") > -1){ chrome25 = uagentLow.search("chrome") > -1 && navigator.appVersion.match(/Chrome\/\d+.\d+/)[0].split("/")[1] > 25; kitkatWebview = uagentLow.indexOf("naver") != -1 || uagentLow.indexOf("daum") != -1; if (chrome25 && !kitkatWebview){ document.location.href = "intent://applink?param=value#Intent;scheme=soribada30;package=com.soribada.android;end"; } else{ $("#____sorilink____").attr("src", 'soribada30://applink?param=value'); } } else if(uagentLow.search("iphone") > -1){ $("#____sorilink____").attr("src", 'soribada30://applink?param=value'); }


내용 추가 (2015-10-10)

ios 9부터 앱링크 실행 시 사용자에게 확인 confirm이 추가되었다.

위의 예시코드에서는 눈에 보이지 않는 iframe에서 앱링크를 실행시키고 있는데, 사용자에게 confirm이 노출되지 않고 사용자가 앱열기 버튼을 탭하지 못하기 때문에 앱이 실행되지 않는다. ios 9 이후 버전에서는 iframe의 src 속성을 이용하지 말고, "location.href"를 사용해야 사용자에게 confirm이 노출되고 앱을 실행시킬 수 있다. ("location.href"를 사용하면 앱이 설치되어있지 않은 사용자에게 에러메시지가 노출된 후 스토어로 이동한다. 참조 : http://developer.naver.com/wiki/pages/UrlScheme)


댓글