참고내용
swift. WKWebView의 MessageHandler이용하기
iOS 앱 내에서 웹을 띄울 수 있는 View
나의 경우에는 웹에 대한 도메인 지식을 가지고 있지 않아 그동안 외주 경험을 통해 iOS WebView에 대해 경험한 부분을 정리하고 한번 리뷰하는 정도의 내용일 것 같다.
이전에는 UIWebView라고 UIKit에서 제공하는 Webview가 있었지만
deprecate 되었으며, WkWebView를 사용 할 수 밖에 없다.
사실 iOS 개발을 하게 되면서 웹뷰와 소통 작업은 여러번 필요했지만 크게 신경쓰이진 않는 내용들이며 웹에 대한 지식이 없어 더 깊은 이해가 어려웠다.
간단하게 WKWebView는 퍼포먼스가 더 좋아졌으며, 가끔가다 처리해주어야 할 쿠키를 저장할 수 없어서 따로 UserDefaults로 저장해서 앱 실행시마다 주입시켜주는 처리를 했던 경험들이 있다.
간단한 코드로 웹뷰 띄우는 방식을 보자.
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))
}
}
실제로 WebView가 많이 있는 앱의 경우엔 자바스크립트와 통신을 해야한다.
WKWebView에서 자바스크립트의 요청을 수신할 수 있고
자바스크립트의 함수를 호출 할 수 있다.
//자바스크립트에 가장 많이 사용되는 예시.
//토큰을 웹뷰에 전달하는 예시를 보자
let token = ""
let script = "sendToken('\(token))"
webView.evaluateJavaScript(script) { result, error in
//콜백 값 및 error을 받을 수 있다.
}
메세지를 수신하는 방법의 경우에는 미리 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
}
}
}
실제로 모든 자바스크립트와의 통신은 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개가 웹뷰 작업을 하면서 발생하는 큰 작업 정도가 될 것 같다.