iOS

iOS) WKWebView vs. SFSafariViewController

kangwook 2022. 8. 22. 22:23

iOS에서 Web을 여는 방식은 뭐 3가지인데 크게 두가지라고 볼 수 있다.

왜냐면 Safari로 여는 방식 2개와 WebView를 띄우는 방식 1개이기 때문이다.

그럼 먼저 Safari부터 차근차근 알아보자. Safari 앱 자체로 여는건 다루지 않을 예정임 ㅇㅇ

SFSafariViewController

  • App 내에서 웹을 여는 방식
  • Safari에서 사용하는 기능들을 전부 사용할 수 있다.
    • 뒤로 가기, 앞으로 가기, 공유하기 등등 다 된다.
    • 하지만 URL을 입력하는 것은 불가능하다.
  • 아이폰의 Safari와 쿠키 정보들을 공유할 수 있다.
    • 하지만 이 정보들을 앱에서는 사용할 수 없다는게 중요하다.
    • 보여주기만 하고 SFSafariViewController 내에서만 활용이 된다는 뜻
  • Delegate를 이용해서 SafariViewController에서 어떤 이벤트가 들어왔을 때 전달하는 것은 가능하다.
  • 주로 간단하게 Web을 보여줘야하는 경우에 사용하는 방법이 되겠다.

WKWebView

자 이제 우리가 많이 쓰는 WKWebView이다.

원래 이전에 UIWebView라고 있었는데 그건 deprecated되고 WebKit을 통해 쓰는 WkWebView가 보편화 되었다.

WKWebView의 특징을 살펴보자.

  • WebView에서 커스텀이 필요한 경우나 App과 Web의 상호작용이 필요한 경우에 주로 사용한다.
  • 기본적으로 사파리에서 사용하던 기능(뒤로 가기, 검색 창 등)은 사용할 수 없고 여러가지 버튼들을 직접 커스텀해서 만들어야 한다. → 장점이자 단점이 될 수 있다.
  • WKUserController를 사용해서 웹과의 상호작용이 가능하고 Javascript코드를 앱에서 전달할 수도 있다.
    • 개발할 때 웹의 Javascript와 iOS Native상에서 통신을 바탕으로 커스터마이징하는 상황이 많을 수 있다.
    • 웹뷰와 앱의 상호작용은 요즘 앱들을 볼 때 필수불가결적인 요소인데 WKWebView를 사용하면 자유롭게 상호작용할 수 있는 것이라 보겠다. (물론 깊게 잘 알아야한다.)
  • WKUIDelegate를 활용해서 WebView가 Alert메세지를 호출했을 때 앱에서 처리 가능하고, 로딩을 완료했을 때 로딩을 시작했을 때의 시점들에 대한 처리도 가능하다.
  • 추가적으로 info.plist에서 App Transport Security Setting에서 Allow Arbitrary Loads 항목 설정이 필요하다.(HTTP 페이지 접근을 시도할 때 접근을 허용하기 위해)
  • iOS 11이상에서는 WKHttpCookieStore에서 쿠키 관리 기능이 추가되었다고 하는데 사실 이건 써보진 않았다.

정리하자면 

종류 Safari WebView
(SFSafariViewController)
WKWebView
지원 버전 iOS 9.0이상 iOS 8.0 이상
(iOS 8.0 미만은 UIWebView를 사용하지만 deprecated 되었다.)
콘텐츠 차단(광고 등) O X
UI/UX 커스터마이징 X O
기능 제어 X O
keychain 연동 O X

이렇게 되겠다.

WebView를 쓰는 방법을 잘 익혀서 요 두 개를 자유롭게 쓸 수 있는 개발자가 되도록 하자.

+

evaluateJavascript(_:completionHandler:)

  • Declaration
func evaluateJavaScript(_ javaScriptString: String, completionHandler: ((Any?, Error?) -> Void)? = nil)
  • 사용 가능 버전
    • iOS 8.0 +
    • iPadOS 8.0 +
    • macOS 10.10 +
    • Mac Catalyst 13.0 +
  • 프레임워크
    • WebKit
  • 사용
    • import WebKit
    • ViewController: WKNavigationDelegate
      • 필수적인 요소는 아니지만 delegate를 위해서 구현하도록 하자
      • 첫 번째 인자인 javaScriptString → 호출할 JavaScript함수 호출
      • 호출할 JavaScript함수에 인자가 들어갈 경우 
        webView?.evaluateJavaScript("javaScriptFunc('\(A)', '\(B)')", ...)
        이렇게 쓰면 된다.

참조