본문 바로가기

iOS

iOS에서 웹뷰를 구현할 때 꼭! 알아둬야할 고려사항에 대하여

iOS에서 흔히들 웹뷰를 구현한다고 했을때, 어떠한 고려사항없이 당연하게도 WKWebView를 사용하는 예제가 많은데요.

사실 iOS에서 웹으로 연결하는 방법은 다양하고, 그 목적과 활용에 따라서 사용에 차이를 두어야합니다. 오늘은 제가 SeoulSalam을 개발하며 고려한 부분과 함께 이에 대해 이야기해보고자 합니다.

 

우선 방법론적인 부분에 대해서 먼저 언급을 하고 각각의 특징을 풀어나가며 마무리로 고려사항에 대해서 정리해보도록 하겠습니다.

 

iOS에서 Web을 띄우는 방법엔 deprecated된 UIWebView를 제외한 세가지 방법이 있습니다.

 

1. UIApplication 클래스에서 제공하는 url open function 사용

func open(
    _ url: URL,
    options: [UIApplication.OpenExternalURLOptionsKey : Any] = [:],
    completionHandler completion: ((Bool) -> Void)? = nil
)

 

가장 기초적인 방법이고, 이렇게 생성된 링크는 디바이스에서 메인으로 설정된 브라우저 앱에서 열립니다. 어떠한 커스텀도 없고, 앱과 전혀 상호작용을 할 수 없습니다. 

따라서 굳이 사용처를 찾아본다면, 앱 내 설정에서 앱의 개발사(혹은 개발자) 페이지, 앱 소개 페이지 등으로 넘길 때와 같이 앱과 소통할 필요가 전혀 없는 경우에 사용할 수 있겠습니다. 사실 이러한 경우에도, 사용자의 흐름을 끊지 않기 위해 SFSafariViewController를 사용하는 것이 적절하다고 생각합니다. 앱에서 내쫓는 느낌이 나니까요. SFSafariViewController 또한 Safari의 기능을 모두 사용할 수 있게 해놓았기 때문에 굳이 이 방법을 채택할 이유는 없겠죠.

그럼에도 불구하고 굳~~~~이 다시 한 번 생각해본다면, Safari를 사용하지 않는 분들을 배려하여(예를들어 Chrome 이나 얼마 전 핫했던 Arc를 아이폰의 기본 브라우저로 설정한 분들에게도 개인화된 경험을 제공하고 싶으시다면, 이 방법을 사용할 수 있겠네요.

 

2. WKWebView

 

여기서 부터 본격적인 WebView에 대한 고찰의 시작입니다. 웹뷰를 사용할 때, 대개 세가지 측면에 대한 고려를 해보면 좋습니다.

 

첫번째로 기능적인 측면입니다:

WKWebView는 WebKit 프레임워크의 일부이고, UIView의 하위클래스입니다. 따라서, 다른 UIView처럼 커스텀을 할 수 있기 때문에, 웹을 앱 내부에 마치 해당 레이아웃의 한 파트인 것처럼 앱에 내장할 수 있습니다. 그러면 앱의 사용성을 해치지 않고 매끄럽게 웹뷰를 인터페이스에 결합시킬 수 있습니다. 따라서 웹기술(HTML, CSS, JS)과 함께 사용하여 앱과 상응하는 레이아웃 스타일링을 할 수 있고, WebKit 프레임워크를 이용하여 앱과 웹을 상호작용시킬 수 있다는 큰 특징이 있습니다. 굉장히 다양해서 직접 공식문서를 살펴보는 것을 추천드립니다만, 간단하게 설명드리자면, 우선 WKWebView는 기본으로 뒤로가기/앞으로가기 기능을 지원하지 않는데, 이를 직접만들 수 있다거나,  웹 페이지 로딩정보를 알 수 있게 한다거나, 웹뷰에서 방문한 웹페이지 리스트를 알 수 있게 하는 등 여러 기능들을 붙여 커스터마이즈할 수 있습니다.

 

두번째로 메모리의 측면입니다:

WKWebView는 웹뷰를 처리하기 위해서 별도의 프로세스를 사용하기 때문에, 웹뷰에 의한 메모리 사용량이 앱의 전체 메모리 사용량으로 집계되지 않습니다. 따라서 앱의 crash를 줄일 수 있습니다. 개인적으로 이는 UIWebView가 deprecated된 이유라고 생각하는데요. 저는 UIWebView를 사용해 본 적은 없습니다만, 조사결과 UIWebView는 앱의 메인 프로세스에서 웹뷰의 처리가 이루어졌다고 합니다.

 

세번째로 Shared Memory에 대한 측면입니다:

이 부분이 WKWebView의 가장 큰 단점이라고 생각되는데요. WKWebView는 쿠키허용설정 및 고급캐시설정을 지원하지 않습니다. 또한 별도의 WebKit Engine에서 웹뷰를 실행하는 것이기 때문에, Safari와 연동되는 iCloud 키체인 등을 사용하지 못합니다. 

이 때문에 발생하는 불편으로는 다음과 같이 흔히겪는 시나리오들이 있을 것입니다.

scenario no.1) 앱을 사용하다가 페이스북 혹은 트위터 링크를 탭하여 이동했는데, 예상되는 뷰가 보이지 않고 로그인페이지가 떠서, 자동완성 없이 하나하나 입력하여 로그인했는데, 원하는 뷰가 아닌 메인 페이지를 보여준다.

scenario no.2) 웹뷰에 상세된 상품 정보를 확인하고 결제를 위한 링크를 타고 갔는데, 내가 자주사용하는 웹의 결제정보가 없어서 해당 주소를 복사하여 Safari로 다시 열고 결제정보를 입력하여 결제한다. 혹은 결제를 포기한다.

 

3. SFSafariViewController

 

기능적인 측면입니다:

SFSafariViewController는 UI 커스터마이즈를 할수가 없습니다. 앱 내에서 별도의 SafariView를 띄워주는 방식이고, 그냥 그거로 끝입니다. 가장 큰 예시로는 Instagram의 광고를 보고 "더 알아보기" 버튼을 누르면 나오는게 SafariView입니다. FullScreenCover 처럼 모달처럼, 혹은 navigate 애니메이션으로 넘어가는 것처럼 보일것입니다. 하지만, WKWebView와 달리 별도의 커스터마이즈를 하지 않고도, 뒤로가기 앞으로가기, Safari로 보기, 방문기록 등 기존 Safari에서 이용할 수 있는 모든 기능이 기본으로 제공됩니다.

 

메모리 측면입니다:

이 또한 별도의 프로세스를 사용하기 때문에, 앱 사용량에 집계가 되지 않습니다. 따라서 이 부분은 WKWebView와 비교할때 동일한 조건입니다.

 

SharedMemory 측면입니다:

SafariView는 쿠키가 Safari와 공유되며(앱과는 공유되지 않음), 캐시도 Safari 정책에 따릅니다. 그리고 WKWebView와 달리 SharedMemory가 shared되며 때문에 따라서 키체인 접근 권한이 있습니다. 물론 별도의 프로세스이며, Safari 브라우저에서 열어주는 것이므로 앱 내에서는 이에 접근할 수가 없고, 접근해서도 안됩니다.

 

4. UIWebView(deprecated)

 

결론:

 

마지막으로 SeoulSalam이 채택한 방법은 SFSafariView인데 그 결정과정에 대해서 이야기해보고자 합니다. SeoulSalam에는 어디에도 없는 서울 시내 할랄레스토랑의 정보를 담고 공유하고 있습니다(크롤링 + 손수따온 고급정보ㅎㅎ, 자랑입니다.) 상세 페이지엔 해당 식당의 전화번호, 위치, 웹사이트 등의 정보를 담고 있는데, 모든 레스토랑의 대표 페이지를 검색해본 결과 트위터, 페이스북 등 다양한 형태로 존재하고 있었습니다. 따라서 WKWebView에서 설명한 첫번째 시나리오와 같은 사용자 경험을 피하고자 선택하게 되었고, 예약 페이지의 형태로 존재하는 사이트도 있었기 때문에 유저의 키체인 접근또한 꼭 있어야하는 부분이었습니다.
따라서, WKWebView에서 제공하는 상세한 커스터마이즈 기능들이 저의 경우엔 위의 이유들에 비해 요구되지 않는 사안들이었기 때문에 이와같이 개발하게 되었습니다.