WKWebView

Eli·2021년 2월 8일
1

iOS

목록 보기
7/11
post-custom-banner

참고내용

swift. WKWebView의 MessageHandler이용하기

Apple Developer Documentation

iOS 앱 내에서 웹을 띄울 수 있는 View

나의 경우에는 웹에 대한 도메인 지식을 가지고 있지 않아 그동안 외주 경험을 통해 iOS WebView에 대해 경험한 부분을 정리하고 한번 리뷰하는 정도의 내용일 것 같다.

이전에는 UIWebView라고 UIKit에서 제공하는 Webview가 있었지만

deprecate 되었으며, WkWebView를 사용 할 수 밖에 없다.

WkWebView와 UIWebView의 차이

  • UIWebView는 UIkit 소속이나 WkWebView는 WebKit의 소속이다.
  • WkWebView는 쿠키를 저장할 수 없다.
  • 퍼포먼스가 UIWebView에 비해 월등히 좋다.
  • WkWebView는 앱 내부의 메모리 리소스로 활용되는 것이 아니라 메모리 경고에 대해 걱정할 부분이 적어진다. (사실 앱 내부라고 해도 그렇게 많은 리소스는 차지 하지 않았던 것 같다.

사실 iOS 개발을 하게 되면서 웹뷰와 소통 작업은 여러번 필요했지만 크게 신경쓰이진 않는 내용들이며 웹에 대한 지식이 없어 더 깊은 이해가 어려웠다.

간단하게 WKWebView는 퍼포먼스가 더 좋아졌으며, 가끔가다 처리해주어야 할 쿠키를 저장할 수 없어서 따로 UserDefaults로 저장해서 앱 실행시마다 주입시켜주는 처리를 했던 경험들이 있다.

Usage

간단한 코드로 웹뷰 띄우는 방식을 보자.

override func viewDidLoad() {
	super.viewDidLoad()
		
	//초기화 및 뷰에 올려주기
	let webView = WKWebView(frame: self.view.frame)
	self.view.addSubView(webView)

	//url 생성해 로드
	if let url = URL(string: "https://www.naver.com") {
			webView.load(URLRequest(url: url))
	}
}

JavaScript 통신

실제로 WebView가 많이 있는 앱의 경우엔 자바스크립트와 통신을 해야한다.

WKWebView에서 자바스크립트의 요청을 수신할 수 있고

자바스크립트의 함수를 호출 할 수 있다.

함수 호출( Swift → JavaScript)

//자바스크립트에 가장 많이 사용되는 예시.
//토큰을 웹뷰에 전달하는 예시를 보자

let token = ""
let script = "sendToken('\(token))"

webView.evaluateJavaScript(script) { result, error in
	 //콜백 값 및 error을 받을 수 있다.
}

메세지 수신 (JavaScript → Swift)

메세지를 수신하는 방법의 경우에는 미리 WkWebView 초기화 시점에 함께 설정을 해주어야 한다.

WKUserContentController는 JavaScript에서 웹뷰에서 호출하게 될 인터페이스를 담을 수 있는 부분이다.

WkWebViewConfiguration의 내부에 프로퍼티로 WebView초기화에 관한 설정들을 해줄 수 있다.

위의 정의한 인터페이스를 받아오는 프로토콜로 WKScriptMessageHandler가 있으며, 이 프로토콜을 따를 수 있게 Delegation을 구현해주어야 한다.

방법은 아래와 같다.

//인터페이스 생성
let contentController = WKUserContentController()
//"callBack"이란 인터페이스를 self로 delegation을 설정
contentController.add(self, name: "callBack")

//인터페이스 내용을 적용
let configuration = WKWebViewConfiguration()
configuration.userContentController = contentController

let webView = WkWebView(frame: self.view.frame, configuration: configuration)
self.view.addSubView(webView)

extension SomeViewController: WKScriptMessageHandler {
		func userContentController(_ userContentController: WKUserContentController, didReceive message: WkScriptMessage) {
				if message.name = "callBack" {
						//위와 같이 내용을 받아와 아래에서 콜백 내용을 처리
						message.body
				}
		}
}

WKUIDelegate

실제로 모든 자바스크립트와의 통신은 WKUserContentController로 정리를 하면 될 줄 알았으나

많은 웹뷰에서 결제 및 인증 등등 하는 화면에서 팝업으로 새 화면을 띄우는 경우가 있었다.

이를 별도로 처리해주지 않으면 그냥 호출을 먹어버리게 되어 있어서. 꼭 처리해주어야만 한다.

실제로 카드 결제 같은 중요 기능들이 이게 원활히 되어야하니 꼭 구현해주어야 한다.

보통 PG사를 연결하게 되면 PG사에서 WKUIDelegate를 어떻게 활용해서 해주어야 할지 가이드 문서를 주는 PG사도 있다.

일단 WKUIDelegate에서 자주 사용되는 3가지 함수정도만 정리를 하려고 한다.

// 새 창열기
// 가장 자주 사용하게 되는 기능인데, 
func webView(_ webView: WKWebView, 
    createWebViewWith configuration: WKWebViewConfiguration, 
                  for navigationAction: WKNavigationAction, 
       windowFeatures: WKWindowFeatures) -> WKWebView? {

		//navigationAction내에 새로 요청하는 webview에 대한 정보가 들어있다.
		//아래와 같은 형식으로 request를 받아 새 웹뷰를 띄우거나 기존 웹뷰에 load 해줄 수 있다. 
		if let url = navigationAction.request.url {
		}
	
}

//Alert
func webView(_ webView: WKWebView, 
runJavaScriptAlertPanelWithMessage message: String, 
     initiatedByFrame frame: WKFrameInfo, 
    completionHandler: @escaping () -> Void) {

		//자바스크립트에서 표시해주는 기본 얼럿에 대해서도 별도 처리를 해주어야한다.
		//이곳에서 message를 포함하는 UIAlertController를 생성해 처리해주면 된다.
}

//Confirm
//Confirmd인데 위의 Alert 방식으로 completionHandler를 호출해주면 된다.
func webView(_ webView: WKWebView, 
runJavaScriptConfirmPanelWithMessage: String, 
initiatedByFrame: WKFrameInfo, 
completionHandler: (Bool) -> Void) {

}

아마 위의 3개가 웹뷰 작업을 하면서 발생하는 큰 작업 정도가 될 것 같다.

profile
애플을 좋아한다. 그래서 iOS 개발을 한다. @Kurly
post-custom-banner

0개의 댓글