iOS DeviceOrientation 권한 처리 실전 노트
iOS Safari에서 DeviceOrientation·DeviceMotion 권한을 안정적으로 받기 위한 사용자 제스처, 폴백, 디버깅 방법을 정리했습니다.
iOS만 유독 까다로운 이유
Android Chrome은 기본적으로 DeviceOrientation과 DeviceMotion 이벤트를 별도 권한 없이 발생시키지만, iOS Safari 13 이후로는 사용자가 직접 버튼을 누른 “제스처 컨텍스트”에서 requestPermission을 호출해야 합니다. 페이지가 로드되자마자 자동으로 권한을 요청하면 브라우저가 무시하거나 false 결과를 돌려줍니다.
Wandcade의 컨트롤러 화면에서 시작 버튼이나 영점 조절 버튼이 가장 먼저 등장하는 이유가 이 때문입니다. 사용자가 한 번 탭을 해야 모션 권한 다이얼로그가 뜨고, 허용한 뒤에야 센서 값을 받아올 수 있습니다.
- 권한 요청은 반드시 사용자 탭 직후에 실행합니다.
- 거절된 경우 다시 요청해도 다이얼로그가 뜨지 않을 수 있습니다.
- iframe 안에서는 권한 요청이 제한될 수 있습니다.
- PWA로 설치된 경우 권한 동작이 일반 Safari와 다를 수 있습니다.
실패하기 쉬운 코드 패턴
useEffect 안에서 DeviceOrientationEvent.requestPermission을 직접 호출하면 사용자 제스처 컨텍스트가 끊겨 권한 요청이 무시됩니다. 권한 요청은 반드시 onClick, onTouchStart 핸들러 내부에서 동기 흐름으로 시작되어야 합니다.
또한 권한이 false로 떨어진 후 새로고침만으로 다이얼로그가 다시 뜨지 않는 경우가 많습니다. Safari 설정 → 웹사이트 → 모션과 방향 접근을 직접 변경하거나, 시크릿 탭에서 다시 여는 식의 안내가 필요합니다.
권한 결과가 granted이더라도 화면 잠금이 풀린 직후나 백그라운드 복귀 직후 잠시 이벤트가 끊길 수 있습니다. 이벤트가 일정 시간 들어오지 않으면 사용자에게 “화면을 가볍게 흔들어 주세요” 안내를 띄우는 폴백이 안정적입니다.
안정성을 높이는 폴백 전략
권한 거절, 이벤트 미발생, 센서 0값 같은 경우에 대비해 두 가지 입력 경로를 만들어두면 사용자 이탈이 줄어듭니다. 첫 번째는 가상 조이스틱이나 슬라이더 같은 터치 입력입니다. 두 번째는 화면 위에서 손가락을 드래그해 기울기 값을 흉내내는 방식입니다.
실제 게임 감각은 센서가 가장 좋지만, 호환이 안 되는 환경에서도 어느 정도 플레이가 가능해야 사이트가 “고장난 곳”으로 인식되지 않습니다. Wandcade는 게임마다 이 폴백을 게임별로 다르게 적용합니다. 슈팅은 가상 조이스틱, 리듬은 터치 좌우, 낚시는 슬라이더 기반 캐스팅 같은 식입니다.
- 센서 미동작 시 가상 입력으로 전환할 수 있도록 UI를 준비합니다.
- 권한 상태(미요청·허용·거절)별로 안내 문구를 다르게 표시합니다.
- 센서 데이터가 일정 시간 0이면 “자세 보정” 안내를 자동으로 띄웁니다.
- 디버그 모드에서 raw 값을 확인할 수 있는 패널을 만들어두면 개발이 빨라집니다.
디버깅 체크리스트
iOS 디바이스에서 센서 문제를 디버깅하려면 macOS Safari → 개발자 메뉴 → 기기 연결을 통한 원격 인스펙터가 가장 빠릅니다. console.log를 띄워두고 권한 다이얼로그 응답, 첫 이벤트 발생 시점, 좌표 축 부호를 확인해야 합니다.
드물게 iOS 업데이트 직후 이벤트 좌표가 바뀐 것처럼 보이는 경우가 있는데, 대부분 화면 방향(landscape vs portrait) 차이입니다. 가로 모드 게임을 만들 때는 screen.orientation을 같이 읽어 부호를 정규화해야 합니다.