WKUserContentController란?
네이티브 앱(iOS)에서 WKWebview를 통해 JavaScript와의 통신을 할 때 도와주는 클래스로, 이게 어떻게 왜 쓰이는지 살펴보기 위해 하이브리드 앱에 대해 먼저 알아보자.
하이브리드 앱이란?
스마트폰 어플리케이션에도 종류가 있다! 웹 앱, 하이브리드 앱, 네이티브 앱 이렇게 크게 세 가지로 나뉜다.
웹 앱
: 웹 방식이지만 앱을 사용하는 것 같은 착각이 들게 하는 방식으로, 웹페이지와 같은 Web을 스마트폰 화면 크기로 줄인 것.
장점 | 단점 |
- PC나 스마트폰 등 단말기 기종에 관계없이 사용이 가능 - 상대적으로 쉬운 웹 언어로 개발하기 때문에 비용과 시간적인 면에서 저렴하고 유지보수가 쉽다. |
- 카메라, 음성 검색 등의 스마트폰 기능은 사용할 수 없고 기능상 제약이 많다. - 애플 스토어 등록 및 판매가 불가 |
네이티브 앱
: 모바일 기기에 최적화된 언어로 개발된 앱으로, 일반적으로 이야기하는 어플리케이션.
유튜브, 인스타그램, 카카오톡 등이 대표적인 네이티브 앱
(안드로이드 앱은 안드로이드 SDK를 이용해 Java 언어로 만들고, 아이폰 앱은 iOS SDK를 이용해 Swift언어로 만듬.)
장점 | 단점 |
- 실행 속도가 빠르고 안정적이며 성능이 높다. - 센서 제어를 통해 카메라, 음성인식과 같은 스마트폰의 기능을 활용할 수 있다. |
- 제작이 어려워 개발 기간이 길고 비용이 많이든다. - 안드로이드 / 아이폰 버전을 따로 만들어야 한다. |
하이브리드 앱
: 위의 두가지 장점을 모두 지닌, 네이티브 앱으로 접근이 가능하지만 실제로는 내부에서 웹뷰를 띄워 실행시키는 형태로 만들어진 앱.
네이버, 다음, 크롬 등이 대표적인 하이브리드 앱.
장점 | 단점 |
- 카메라, 음성인식과 같은 스마트폰의 기능을 활용할 수 있다. - 웹(HTML)으로 개발하기 때문에 개발 및 유지보수가 간단하다. (안드로이드/아이폰 상관없고, 배포 후에도 웹에서 수정/보완 가능) |
- 상대적으로 네이티브 앱보다 속도가 느리다. |
▶︎ 이러한 하이브리드 앱을 개발하는 경우,
웹 뷰(WKWebView)를 실행할 때 네이티브(iOS)와 웹(JS) 간의 통신을 도와주는 것이 바로 WKUserContentController
Apple Developer 사이트를 살펴보면,
: An object for managing interactions between JavaScript code and your web view, and for filtering content in your web view.
class WKUserContentController : NSObject
사용법?
웹 뷰를 생성하기 전, 웹 뷰 셋업할 때 WKUserContentController()를 생성해주고,
이를 WKWebViewConfiguration의 프로퍼티인 userContentController에 할당해주어라.
우선 웹 뷰 띄우기는 WKWebView 사용해서 웹 뷰 띄우기 참고!
1. WKUserContentController()로 JavaScript 코드에서 불러올 메세지 핸들러 추가해주기 (웹에서 네이티브 호출할 때)
func add(WKScriptMessageHandler, name: String)
add 함수로 간편하게 불러올 수 있는데, 다음과 같이 사용이 가능하다.
let contentController = WKUserContentController()
contentController.add(self, name: "doSomething")
2. WKWebViewConfiguration에 userContentController로 할당해주기
let config = WKWebViewConfiguration()
//config.preferences.javaScriptEnabled = true
//config.preferences.javaScriptCanOpenWindowsAutomatically = true
config.userContentController = contentController
3. WKWebView 생성
mWebWK = WKWebView(frame: .zero, configuration: config)
//mWebWK.uiDelegate = self
//mWebWK.navigationDelegate = self
mWebWK.translatesAutoresizingMaskIntoConstraints = false
let url = URL(string: "url")!
let request = URLRequest(url: url)
mWebWK.load(request)
view.addSubview(mWebWK)
4. extension으로 WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler 프로토콜 상속해주기
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("message: \(message.name), body: \(message.body)")
if (message.name == "doSomething") {
//js에서 받아온 데이터 (보내주는 데이터가 있다면)
let body = message.body
//js로 값 넘겨줄 때
mWebWK.evaluateJavaScript("sendInfo", completionHandler: nil)
}
}
일반적으로 네이티브에서 JS함수 호출할 때는 보통 evaluateJavaScript 사용.
func evaluateJavaScript(_ javaScriptString: String,
completionHandler: ((Any?, Error?) -> Void)? = nil)
js -> ios 호출만 할 때 예시
Javascript
function() {
if (a) {
var t = u();
if (t.android)
window.android.toDoStartRecord();
else if (t.iphone) {
var n = {
action: "toDoStartRecord"
};
window.webkit.messageHandlers.LoungeBridge.postMessage(n)
}
}
Swift iOS
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if (message.name == "LoungeBridge") {
let body = message.body as? [String:Any] ?? [:]
print("Message Body = \(body)")
let action = body["action"] as? String ?? ""
if (action == "toDoStartRecord") {
//do something
}
}
}
js -> ios 호출 및 전달하는 값이 있을 때 예시
Javascript
function(e) {
if (a) {
var t = u();
if (t.android)
window.android.setJwtToken(e);
else if (t.iphone) {
var n = {
action: "setJwtToken"
};
n.param = e,
window.webkit.messageHandlers.LoungeBridge.postMessage(n)
}
}
Swift iOS
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if (message.name == "LoungeBridge") {
let body = message.body as? [String:Any] ?? [:]
print("Message Body = \(body)")
let action = body["action"] as? String ?? ""
if (action == "setJwtToken") {
let param = body["param"] as? String ? ""
}
}
}
혹시나 제 글이 도움이 되셨다면 하트 한번 눌러주시면 감사하겠습니다 🥰
iOS 개발자분들 모두 화이팅입니다👍🏻
'초보 iOS 개발자의 일상 > 개발 업무' 카테고리의 다른 글
[Swift iOS, JavaScript] url schemes 사용하여 웹에서 앱 호출 및 앱스토어 연결하기 (10) | 2021.04.16 |
---|---|
[Swift iOS] FCM(Firebase Cloud Messaging) 이용하여 Push 설정 (0) | 2021.04.15 |
앱 심사를 통과하지 못함. 사유 안뜰 때! 심사 거부 사유 확인하는 법 (0) | 2021.04.12 |
6년 된 Object-C 프로젝트 수정 요청 (0) | 2021.04.07 |
기존프로젝트 UI 변경_ Storyboard 충돌 (0) | 2021.04.07 |