# 모바일 웹에서 앱 실행하기 deeplink 사용법

앱의 dau를 늘려 파생상품을 판매하거나 홍보를 위하는 등 다양한 이유로 모바일 웹애서 특정 앱 또는 자사 앱을 실행하고 싶을 때가 있습니다.

이때 모바일 앱 딥링크는 앱으로 전환율과 유지율을 크게 높일 수 있습니다.

모바일 앱 딥링크는 현재 앱이 설치된 경우 사용자가 링크를 클릭하면 앱이 열리고 개발자가 원하는 화면으로 이동할 수 있습니다. 앱이 설치되지 않은 경우는 playstore 또는 appstore로 redirect시켜 앱을 다운받도록 권고 할 수 있습니다.

서론은 여기까지 하고 제가 구현한 딥링크에 대해 알아보겠습니다

저는 모바일 웹과 앱의 웹뷰를 담당하였고, 앱 스킴을 이용해서 앱을 실행하는 작업을 하였습니다. 즉, 이 포스팅은 안드로이드 또는 ios에서 앱 스킴을 만드는 방법은 포함하지 않습니다.

스킴 기반 딥링크는 url을 앱과 연결한다는 아이디어로 만들게 됩니다. (스킴 기반 딥링크: youapp://, universal link: https://yourdomain.com/) 사용자가 URL을 클릭하면 시스템이 설치된 앱을 실행합니다.

# 전제조건

앱이 실행되려면 앱이 깔려있어야하겠죠?? 그렇기 때문에 유저가 앱을 깔지 않은 경우 앱스킴을 몇번을 실행해도 사용자는 오류 메시지를 보게 되거나 아무 일도 일어나지 않을 것입니다. 웹 상에서 기기에 앱이 설치되어 있는지를 직접 확인할 수 있는 방법은 없지만, 앱이 설치되어 있다면 이를 불러오거나, 설치되어 있지 않다면 사용자를 App Store나 playstore 또는 다른 장소로 연결할 수 방법은 여러가지가 있습니다

저는 이번 예시에서 앱이 설치되지 않은 경우 앱을 다운받을 수 있는 alert를 제공하는 방법으로 구현하겠습니다

# 딥링크

먼저 앱이 있다고 가정하고 딥링크를 실행합니다

딥링크 URL은 yourapp://path/이라고 가정합니다

const exeDeepLink = () => {
  url = "yourapp://path/";
  location.href = url;
};

위의 경우 앱이 설치된 경우 앱이 실행되고, 앱이 설치되지 않았다면 exeDeepLink함수는 아무 작업도 수행하지 않습니다

# 설치 유도

앱이 설치되지 않아 exeDeepLink에서 아무 실행이 없었다면 timeout기능을 통해 app을 다운받도록 유도합니다

아래코드는 checkInstallApp 가 실행되면 0.5초 후에 앱 다운로드 하겠냐는 팝업을 띄우는 코드입니다. 0.2초 마다 브라우저가 닫히는 것을 체크하여 다운로드 팝업을 띄우지 않습니다.

const checkInstallApp = () => {
  const clearTimers = () => {
    clearInterval(check);
    clearTimeout(timer);
  };

  const isHideWeb = () => {
    if (document.webkitHidden || document.hidden) {
      clearTimers();
    }
  };
  const check = setInterval(isHideWeb, 200);

  const timer = setTimeout(function() {
    redirectStore();
  }, 500);
};

const redirectStore = () => {
  const ua = navigator.userAgent.toLowerCase();

  if (window.confirm("스토어로 이동하시겠습니까?")) {
    location.href =
      ua.indexOf("android") > -1
        ? "https://play.google.com/store/apps/details?id=xxxxxx"
        : "https://apps.apple.com/kr/app/xxxxxx";
  }
};

# 종합 코드

위에 앱 딥링크 코드와 앱다운로드 코드를 종합하면 아래와 같습니다 react로 구현하였습니다

버튼 클릭시 앱 딥링크가 실행되어 앱이 깔린 경우 앱이 실행되고, 그렇지 않은 경우 다운로드 팝업이 띄워집니다

import { useState } from "react";
import styled from "styled-components";

const Index = () => {
  const [isOpenModal, setIsModalOpen] = useState(true);
  const redireactApp = () => {
    exeDeepLink();
    checkInstallApp();
  };

  function checkInstallApp() {
    function clearTimers() {
      clearInterval(check);
      clearTimeout(timer);
    }

    function isHideWeb() {
      if (document.webkitHidden || document.hidden) {
        clearTimers();
      }
    }
    const check = setInterval(isHideWeb, 200);

    const timer = setTimeout(function() {
      redirectStore();
    }, 500);
  }

  const redirectStore = () => {
    const ua = navigator.userAgent.toLowerCase();

    if (window.confirm("스토어로 이동하시겠습니까?")) {
      location.href =
        ua.indexOf("android") > -1
          ? "https://play.google.com/store/apps/details?id=xxx"
          : "https://apps.apple.com/kr/app/xxx";
    }
  };

  function exeDeepLink() {
    url = "yourapp://path/";
    location.href = url;
  }

  return (
    <DeepLinkBlock>
      <div className="modal">
        <p className="title">앱을 여시겠습니까?</p>
        <div className="button-group">
          <button className="open btn" onClick={redireactApp}>
            네 열래요
          </button>
        </div>
      </div>
    </DeepLinkBlock>
  );
};

const DeepLinkBlock = styled.div`
  background: #d1d1d1;
  position: fixed;
  overflow: hidden;
  height: 100vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
  .modal {
    width: 278px;
    height: 171px;
    padding: 26px 14px 14px;
    background: #ffffff;
    box-shadow: 0px 4px 4px rgba(192, 192, 192, 0.25);
    border-radius: 8px;
    position: relative;
    bottom: 50px;
    .title {
      font-weight: bold;
      font-size: 17px;
      margin-bottom: 12px;
    }
    .desc {
      font-size: 12px;
      color: #777777;
    }
    .button-group {
      display: flex;
      justify-content: space-around;
      margin-top: 38px;
      .btn {
        height: 40px;
        width: 120px;
        background: #eeeeee;
        color: #555555;
        font-size: 14px;
        letter-spacing: -1px;
        border-radius: 6px;
      }
      .open {
        background: orange;
        color: #ffffff;
      }
    }
  }
`;

export default Index;
#react
노경환
이 글이 도움이 되셨다면! 깃헙 스타 부탁드립니다 😊😄
최근변경일: 4/27/2024, 7:12:59 AM