Blog

Android, IOS Webview 개발 팁

최근에 webview를 사용하는 서비스의 SPA작업을 진행하면서 OS별 이슈 및 솔루션을 정리해 보았다.

아래 정리된 내용은 정답도 최선도 아니지만 참고하면 많은 삽질을 줄이고 즐겁게 개발할 수 있을 것 같다.

  1. IOS position:fixed + 키패드 활성화시 이슈
    • IOS에서 position:fixed 속성을 사용하면 키패드 활성화 시 element가 화면 밖으로 사라지거나 제대로 위치를 잡지 못한다. 구글링을 통한결과 이미 오래된 이슈이며 position:fixed <-> absolute, static등의 속성을 키패드 유무에 따라 처리하는 방법말고는 없는 것 같다.
      * 해당 방법 사용시 발생하는 추가 이슈와 대응방법은 아래 3. 에 기술하였다.
      * stackoverflow에 증상은 다르지만 fixed가 원인이 되어 UI가 깨지는 증상들을 쉽게 찾아볼 수 있다.
      http://stackoverflow.com/questions/14267527/uiwebview-and-css-fixed-position
      위 링크된 내용은 element에 fixed 값을 사용했는데 처음에는 페이지와 함께 이동하고 그다음 스크롤부터는 fixed가 먹힌다는 내용인데 fixed를 가능하면 사용하지 않는게 편할 것 같다. 최신 OS 버전에서도 Iphone5, 6/6plus 에서 다른 증상이 나타났다. 사실 앱버전에 따른 웹뷰차이일 수 도있어 꼭 짚어 디바이스 문제라고 할 순 없지만 확인해 볼 필요가 있다.
  2. input태그 사용시 form태그 부재 상황에서 오동작
    • form태그로 감싸지 않은 checkbox, radio 속성 사용시 이슈
      • UI만을 위해서 type이 checkbox, radio인 input을 form태그로 감싸지 않고 사용할 경우 정상적인 기능을 수행하지 못할 수 있다. UI개발만을 위해서 사용하더라도 input태그는 form태그 내에 두는 것이 좋다.
    • input type에 따른 키패드 타입 이슈
      • input type=’search’시 키패드에 ‘search’라는 버튼이 노출된다. Android의 경우는 form 태그 유무와 상관없이 기대한 동작을 수행하였지만 IOS의 경우 form 태그로 감싸지 않으면 ‘return’ 버튼이 노출된다. 본인의 경우 SPA 작업을 하면서 submit 이벤트를 통해 서버로 값을 전달할 일이 없어져 form테그를 사용하지 않고 input태그만 사용했는데 SPA작업 이라도 form태그를 사용하는게 좋을 것 같다.
    • SPA에서 input type ‘search’일 경우 ‘search’ 키패드 사용시 이슈
      • SPA는 ajax를 이용한 API콜 말고는 페이지가 새로고침 될 일이 없다. 하지만 form태그 내에 search 타입의 input태그가 있으면 키보드의 검색 버튼이 노출되고 이버튼을 사용자가 누르게되면 submit 이벤트가 발생하면서 페이지가 새로고침된다. Android, IOS 동일하며 SPA 작업시 submit 이벤트를 취소해주는 코드가 필요하다.
  3. 서비스의 구동 환경 및 OS 구분 값, 키패드 활성화 상태 값이 있으면 좋다.
    • UI개발을 위해서 서비스가 구동되는 환경이 앱인지, 모바일 웹인지 그리고 IOS 인지 Android 인지의 구분 값과 IOS경우 키패드 활성화 여부 상태 값이 있으면 좋다. 사실 좋다기보다 꼭 필요한 것 같다. 본인이 SPA 작업시 style을 위해서 body나 상위 엘리먼트에 다음과 같은 클래스를 추가하고 분기가 필요한 UI는 4가지 값의 조합으로 분기가 필요한 UI에 대응하였다.
      ex) .app/.mweb, .ios/.anroid
      추가로 1.에 언급된 position:fixed 이슈를 해결하기 위해 키보드 활성화 여부 상태 역시 클래스(‘body.keyboard_on’)로 처리하여 사용하였다. 사실 UI디자인을 위해서 사용한거고 실행환경 및 상태에 관한 모델을 만들고 해당 모델로 element에 적잘한 class값 업데이트를 동해 디자인을 처리하였다. 언급된 분기 값들은 아래의 경우에 사용된다.

      • IOS에서 앞서 언급된 position:fixed 속성과 키패드가 활성화, 비활성화 되는 경우 UI구현을 위해 position:fixed<->static로 토글되는 시점에 reflow가 발생하는데 이때 웹뷰 위치가 하단으로 스크롤이 되어있는 경우에 키보드가 활성화, 비활성화 되면 뷰가 상단으로 애니메이션 되면서 끌어올려 지는데 끌어올려 지면서 reflow혹은 repaint가 발생하고 상단으로 도착하고 나서는 element가 사라지는 케이스가 있다. 이슈 해결을 위해서 스크롤시 키패드 활성여부 값과 OS 분기값을 사용하여 강제로 키보드를 숨기고 position 속성 값을 변경 하도록 처리하였다.
      • Android와, IOS의 웹뷰 및 키패드 활성화 방식이 다를 수 있다. 본인이 작업한 환경에서는
        – IOS경우 키패드 활성화 시 웹뷰를 리사이징 하고,
        – Android 경우는 키패드를 웹뷰위로 레이어? 방식으로 띄우도록 되어있었다.
        위 방식의 차이로 디자인에 따라 Android와 IOS의 스타일이 다르게 처리되야할 경우 사용된다.
  4. OS별 웹 뷰 디버깅
    • Android
      • Chrome USB리모트 디버깅을 사용
        디바이스를 PC와 USB로 연결한 다음 PC크롬에 ‘chrome://inspect/#devices’ 입력하면 디바이스의 크롬탭과, 웹뷰 리스트가 나온다. 디버깅할 페이지 주소를 클릭하면 PC에서 웹뷰(모바일 크롬) 디버깅이 가능하다.
        *’chrome://inspect/#devices’에서 포트포워딩하시면 로컬서버 띄우고 모바일 크롬으로 확인 가능하다.
    • IOS
      • Safari 개발자 메뉴 디버깅 사용
        디바이스를 Mac과 USB로 연결한 다음 앱에서 설정->사파리->고급->웹속성 활성화를 하고 Mac safari -> 개발자용 메뉴에서 활성화된 페이지 주소 클릭하면 Mac에서 웹뷰(모바일 사파리) 디버깅이 가능하다.
        *Mac의 safari 개발자용 메뉴에서 활성화된 주소 클릭하면 xCode에서 IOS 시뮬레이터내 safari도 디버깅이 가능하다.
        *IOS 경우 개발자 등록된 폰이라도 되는폰이 있고 안되는 폰이 있던데 모바일 유닛에서 웹뷰 디버깅할 일이 없어서 그런지 Safari 디버깅과 관련해서는 정확한 답변을 얻지 못다.
        만약 앱자체에서 가능하도록 되어있다면 언급했던대로 ‘웹속성’을 활성화하면 사용할 수 있다.
  5. App과 WebView간 메소드 호출방법 
    • 앱과 웹뷰간 js호출을 원활하게 하기 위해서는 모바일 작업자와 협의하여 자바스크립트 소스코드에 util메소드로 관련 기능을 추가해두는게 좋을 것 같다. 아래는 작업했던 상황에서의 처리내용이다.
      • Android
        • callWeb -> webview.loadUrl(‘javascript:자바스크립트 메소드 경로’);
          callApp -> 자바스크립트 window객체 사용하여 웹뷰에서 받을 수 있도록 전달
      • IOS
        • callWeb -> ?? 모바일 유닛에 확인 후 업데이트하도록 하겠습니다.
          callApp -> DOM iframe 사용하여 iframe의 요청 url을 IOS에서 설정된 프로토콜(google-ios://) + URI(타입, 호출메소드명) + 쿼리스트링(옵션파라미터) 조합으로 보내면 앱에서 캐치하여 사용한다. 물론 구현 방법에 따라 API콜 url 형태는 달라질 수 도있는 것 같다.
  6. HTML5 Localstorage 사용시 주의사항
    • IOS, Android 모두에서 웹뷰를 개인정보 보호모드로 사용하면 로컬스토리지를 사용할 수 없다. 본인의 경우 최근검색의를 localstorage를 사용하여 처리하였는데 개인정보 보호모드의 경우를 체크하여 사용할 수 없을 경우 적절한 안내 문구를 노출시키도록 처리하였다. 로컬스토리지 주의사항 관련된 내용은 작성된 포스트를 참고하길 바란다.
  7. webview에서 OS별 키보드 컨트롤 제한
    • Android는 앞서 언급한 callApp 방식을 사용하여 OS에서 키보드 활성화 및 비활성화가 가능하나 IOS는 OS에서 키보드자체 컨트롤이 불가능하여 포커스 여부에 따라서만 키보드 컨트롤 가능하다. 키보드 노출여부에 따라 UI가 변경되는 경우 앞서 언급한 ‘서비스의 구동 환경 및 OS 구분 값, 키패드 활성화 상태 값’을 사용하여 OS별로 처리할 필요가 있다.

 

언급된 내용은 작업간 발생 했던 이슈를 정리한 내용이라 직접 격지 못한 이슈가 많이 있을 수 있습니다.

추가 되었으면 하는 부분이 있으면 아래 댓글로 남겨주시면 반영하도록 하겠습니다.

감사합니다.

 

 

  • http://gutmate.github.io formation.p

    좋은글 잘 보았습니다.
    궁금한 부분이 있어서 질문 하나 드려봅니다.
    제가 iOS position:fixed focus 키보드 문제로 웹뷰에서 고생을 하고 있습니다.
    쓰신 글에서
    [스크롤시 키패드 활성여부 값과 OS 분기값을 사용하여 강제로 키보드를 숨기고 position 속성 값을 변경 하도록 처리하였다.]
    [IOS경우 키패드 활성화 시 웹뷰를 리사이징 하고,]
    라는 글이 있는데 이 부분이 제 짧은 견해로는 이해가 잘 가지 않습니다.
    혹시 어떻게 처리하신건지 알수 있을까 싶어서 이렇게 글을 남깁니다.

    • http://superjang.com Jae Won Jang

      안녕하세요.
      확인이 많이 늦어서.. 이미 해결 하셨겠지만 문의 주신 부분 답변드립니다.

      일단 fixed속성 엘리먼트와 키보드가 공존할 수 없는 상황이므로
      1. 키보드가 나오는 시점에 fixed 속성을 absolute나 다른 속성으로 변경을 합니다.
      2. 키보드가 사라지는 시점에 fixed 속성을 다시 줍니다.
      3. 이걸 IOS에서만 동작하도록 OS분기를 시켜줍니다.

      답변이 늦어 죄송합니다 ^^;