iOS에서 WKWebView 붙이는 방법
02 Aug 2018 |프로젝트내에 loginPage.html이 있다는 가정하에 다음과 같이 하면 된다.
참고로 import WebKit
를 반드시 해주어야 한다.
//request 만들고
guard let htmlUrl = Bundle.main.url(forResource:"loginPage", withExtension:"html") else { return }
let request = URLRequest(url:htmlUrl)
webview.load(request)
// UI 구성
self.view.addSubview(webview)
webview.layer.borderWidth = 4.0
webview.layer.borderColor = UIColor.red.withAlphaComponent(0.3).cgColor
webview.addToSuper(top: 10, left: 10, bottom: 10, right: 10)
iOS에서 javaScript를 사용해 HTML를 변경하는 예제
전체 코드를 우선 보자.
작동 순서는 아래와 같다.
- 웹페이지 로딩을 한다
- 로딩이 끝나면 자바스크립트 파일내의 mobileHeader()를 실행한다
- mobileHeader()는 웹페이지내의 h1 태그를 보고 내용을 변경한다
- 변경된 웹페이지를 갱신해준다.
class JSFromiOSViewController: UIViewController {
var webview:WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
initWebview_with_callJsFunc_modifyHTML()
loadUrl()
}
func initWebview_with_callJsFunc_modifyHTML(){
//contents 만듬.
let contentController = WKUserContentController()
let userScript = WKUserScript(source: "mobileHeader()",
injectionTime: .atDocumentEnd,
forMainFrameOnly: true )
//mobileHeader()라는 javaScript 함수가 html로딩완료후 호출됨.
contentController.addUserScript(userScript)
//config 만듬
let config = WKWebViewConfiguration()
config.userContentController = contentController
//put it all together
//자바스크립트 함수를 실행시킬 준비를 미리하고, 이를 configuration에 넣고
//이를 다시 userContentController에 저장해둔후
//웹뷰를 만든다.
webview = WKWebView(frame: CGRect.zero , configuration: config )
}
func loadUrl(){
//request 만들고
guard let htmlUrl = Bundle.main.url(forResource:"loginPage", withExtension:"html") else { return }
let request = URLRequest(url:htmlUrl)
webview.load(request)
// UI 구성
self.view.addSubview(webview)
webview.layer.borderWidth = 4.0
webview.layer.borderColor = UIColor.red.withAlphaComponent(0.3).cgColor
webview.addToSuper(top: 10, left: 10, bottom: 10, right: 10)
}
}
- initWebview_with_callJsFunc_modifyHTML() 메소드:
우선 WKUserContentController
를 이용하여 WebView를 로딩하기 전에 JavaScript 메소드 연동을 미리해주어야 한다. WKWebViewConfiguration
의 userContentController` 의 인자로 세팅해준다.
- loadUrl() 메소드:
번들로부터 HTML파일의 url을 가져오고 나서 webview.load(request)
를 사용하여 웹뷰를 로딩하는 부분.
JavaScript를 설정하는 부분을 간단히 그려보면 다음과 같다.
ascii. 그림 들어갈 곳.
다음은 필요한 HTML, JS파일이다.
loginPage.html 는 다음과 같다.
<!--여기부터가 웹페이지 구성내용임.-->
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {
padding-top: 40px;
}
</style>
<title>WKWebView Demo</title>
<meta charset="UTF-8">
</head>
<body style="background-color: gray;">
<h1>JS to Webview Sample</h1>
<form class="form-signin" role="form">
<div class="form-content">
<label for="email" class="form-email">Already an account?</label>
<br />
<input type="email" id="email" class="form-control" placeholder="Email" required autofocus />
<br />
<input type="password" id="password" class="form-control" placeholder="Password" required>
<br />
<button class="btn btn-lg btn-primary btn-block" type="button" onClick="sendLoginAction()">
Submit
</button>
</div>
</form>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
main.js의 내용
function sendLoginAction() {
try {
webkit.messageHandlers.loginAction.postMessage(
document.getElementById("email").value + " " + document.getElementById("password").value
);
} catch(err) {
console.log('The native context does not exist yet');
}
}
function mobileHeader() {
document.querySelector('h1').innerHTML = "iOS에서 호출된 증거(이 텍스트는 main.js에서 가져옴)";
}
레퍼런스: // ref: https://benoitpasquier.com/ios-webkit-swift-and-javascript/ // ref: https://github.com/popei69/WebkitSample/blob/master/WebkitSample/ViewController.swift
iOS에서 javaScript를 사용해 HTML를 변경하는 예제
전체 코드
import UIKit
import WebKit
// HTML상의 js를 invoke시켜 iOS로 응답을 받아냄.
// 예) 웹상에 입력했던 "로그인아이디", "암호"를 iOS로 전송해줌.
class JSToiOSViewController_simple: UIViewController{
var webview:WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
initWebview_then_callFromJs()
loadUrl()
}
func initWebview_then_callFromJs(){
//contents컨트롤러 만듬.
let contentController = WKUserContentController()
contentController.add(self, name:"doneAction")
//config 만듬
let config = WKWebViewConfiguration()
config.userContentController = contentController
//위 인자사용한 초기화
webview = WKWebView(frame: CGRect.zero , configuration: config )
}
func loadUrl(){
//request 만들고
guard let htmlUrl = Bundle.main.url(forResource:"buttonPress", withExtension:"html") else { return }
let request = URLRequest(url:htmlUrl)
webview.load(request)
// UI 구성
self.view.addSubview(webview)
webview.layer.borderWidth = 4.0
webview.layer.borderColor = UIColor.red.withAlphaComponent(0.3).cgColor
webview.addToSuper(top: 10, left: 10, bottom: 10, right: 10)
}
}
extension JSToiOSViewController_simple: WKScriptMessageHandler{
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "doneAction" {
print("JavaScript 에서 메시지가 왔어요 \(message.body)")
}
}
}
buttonPress.html
<html>
<head>
<title>WKWebView Demo</title>
<meta charset="UTF-8">
</head>
<body style="background-color: gray;">
<h1>js함수를 기다림....내용을 적고, 완료버튼을 누르세요</h1>
<input type="email" id="email" class="form-control" placeholder="Email" required autofocus />
<br />
<button class="btn btn-lg btn-primary btn-block" type="button" onClick="sendDoneAction()">
완료
</button>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
MAIN.JS
function sendDoneAction() {
try {
webkit.messageHandlers.doneAction.postMessage ( document.getElementById("email").value );
} catch(err) {
console.log('The native context does not exist yet');
}
}
일단 App을 실행한 하면 다음과 같은 화면이 나온다.
먼저 HTML파일과 JavaScript 쪽을 보자.
HTML 페이지가 로딩되면 텍스트필드와 버튼이 있다. 여기에 내용을 “하하호호”라고 적고 완료버튼
을 누른다.
버튼을 누르면 onClick
에 연결된 sendDoneAction()
이 실행된다. 이는 main.js에 있는 메소드이다.
sendDoneAction()
내부에는 webkit.messageHandlers.doneAction.postMessage
가 있다. 그 코드를 자세히 보면 doneAction
이 포함됨을 알 수 있다.
이 doneAction이라는 문자열을 가지고 iOS쪽과 통신을 한다고 보면 된다.
이제 iOS쪽을 보자.
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
델리게이트가 있다.
이곳에서 아래와 같은 코드를 통해 javaScript로 부터 전송된 메시지 내용을 받을 수 있다.
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "doneAction" {
print("JavaScript 에서 메시지가 왔어요 \(message.body)")
}
}
알아야 할 것이 있는데, 위 델리게이트가 정상적으로 동작하기 위해서 WKWebView 설정할 때 아래와 같이 doneAction
가 포함된 부분을 명시 해주어야 한다.
//contents컨트롤러 만듬.
let contentController = WKUserContentController()
contentController.add(self, name:"doneAction")
전체 구조
전체 구조를 보면 다음 그림과 같다.
sendDoneAction()의 화살표를 따라가보자.
이상.
Comments