모바일, 태블릿, 데스크탑 구분하기

천영석·2021년 9월 2일
0

오늘 개발을 하다가 생각도 못해본 이슈를 만나게 되었다. 모바일과 태블릿에서는 터치가 가능하기 때문에 터치가 가능한 UI를 제공하고, 데스크탑에서는 터치가 불가능한 UI를 제공하도록 구현하려고 했다. 그러려면 모바일, 태블릿과 데스크탑을 구분해야 했다.

찾아보니 navigator.userAgent를 사용하면 현재 접속 중인 단말기의 환경을 알 수 있었다. iPad로 접속하면 Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) ...,
갤럭시로 접속하면 Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) ...
데스크탑인 경우 Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...
이렇게 환경을 나타내고 있었다. 딱 보니 iPad, Android와 같은 모바일이나 태블릿을 나타내는 문자열을 정규표현식으로 찾으면 될 것 같았다.

하지만 모든 태블릿과 모바일의 환경을 알지 못해 검색해보니 Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobi|mobi 이처럼 엄청 많은 환경이 존재했다. 하지만 userAgent를 사용할 땐 조심하라고 MDN에서 말하고 있다. 왜냐하면 브라우저마다 제공하는 환경이 다를 수 있고, 새로운 기기일 때도 바뀔 수 있으며 그렇기 때문에 모든 경우의 수를 추가해줘야 하기 때문이다. 즉, 100%를 고려하기가 어렵다는 것 같다.

이 글을 보고, 내 아이패드로 실험을 해봤다. 모바일 브라우저 여부 확인하기사이트에 들어가면 현재 나의 userAgent가 나온다. 확인해보니 Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) ...가 아닌 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) ... 이렇게 나오는 것이다. 아니 왜 iPad가 아니라 Macintosh로 나오는거지?????

알고보니 애플에서 아이패드도 데스크탑화를 하겠다고 계속 밀고 있다고 한다. 그래서 사파리 브라우저에서는 아이패드가 Macintosh로 등록되어 있다. 하지만 갓 크롬에서는 iPad라고 정상적으로 나온다. 그래도 사파리를 아예 배제할 순 없으니... 고쳐야 했다.

방법을 찾아보다가 같은 고민을 하는 블로그를 찾았다. navigator.maxTouchPoints로 해결할 수 있다는 것이다. 해당 속성은 동시 최대 터치수를 알려주는 것인데, 일반적으로 데스크탑은 터치가 불가능하기 때문에 0이다. 그리고 모바일 기기나 태블릿은 1 이상일 것이다. 이를 이용해 애플의 Macintosh를 찾아내고, 이 안에서 maxTouchPoints를 검사해서 1 이상이면 태블릿으로 보게 되었다.

나머지는 문제 없기 때문에 그냥 정규표현식으로 검사하는 것으로 했다.

결국 나온 코드는 아래와 같다.

const isMobile = (() => {
  const { userAgent, maxTouchPoints } = window.navigator;

  const isMac = /Macintosh/i.test(userAgent);

  if (isMac && maxTouchPoints > 0) return true;

  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobi|mobi/i.test(
    userAgent
  );
})();

즉시실행함수로 실행했는데, 모바일 기기를 검사하는 과정은 처음 로드되었을 때 한번만 검사해놓고 값으로 사용하면 된다고 생각했기 때문이다. 아직 배포가 되지 않아 아이패드에서 실험을 못해봤는데, 잘 되면 좋겠다.(윈도우에서 아이패드를 로컬로 연결하는 것이 잘 안된다...ㅠㅠ)

참고:

profile
느려도 꾸준히 발전하려고 노력하는 사람입니다.

0개의 댓글