Swift(스위프트): 오프라인 웹 페이지에서 자바스크립트 실행 및 alert, confirm, prompt 띄우기 (스토리보드)
이전 글에서 이어집니다.
소개
웹킷뷰(WKWebView) 에서 자바스크립트를 실행하려면 자바스크립트 모드가 활성화되어야 합니다. 다음 코드를 뷰 컨트롤러에 추가합니다. iOS 14 버전과 이전 방식에 차이가 있습니다.
자바스크립트 실행 방법
딜리게이트 구현 추가
먼저 딜리게이트를 구현하는 뷰 컨트롤러의 extension을 추가합니다.
1
2
3
extension ViewController: WKUIDelegate, WKNavigationDelegate {
}
WKWebView 초기화
다음 웹킷뷰를 초기화하는 함수를 작성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func loadHelpPage() {
// 웹 파일 로딩
webView.uiDelegate = self
webView.navigationDelegate = self
let pageName = "index"
guard let url = Bundle.main.url(forResource: pageName, withExtension: "html", subdirectory: "webpage") else {
return
}
webView.loadFileURL(url, allowingReadAccessTo: url)
if #available(iOS 14.0, *) {
webView.configuration.defaultWebpagePreferences.allowsContentJavaScript = true
} else {
// Fallback on earlier versions
webView.configuration.preferences.javaScriptEnabled = true
}
}
HTML 파일에 자바스크립트 작성
다음 HTML 파일에 자바스크립트를 작성합니다.
1
2
3
4
5
6
7
8
9
10
<body>
<h1 id="title">안녕하세요</h1>
<img src="image.png" width="100%">
<a href="https://google.com">하이퍼링크</a>
<button id="btn-alert">자바스크립트</button>
<script>
document.getElementById("title").textContent = "Javascript"
</script>
</body>
이렇게 하면 원래 제목은 안녕하세요 이지만 자바스크립트가 실행되면서 Javascript 로 변하는 것을 알 수 있습니다.
경고창은 어떻게 띄움?
하지만 일반 웹브라우저에서는 당연하게 되던 것들이 여기서는 작동하지 않는 경우가 많습니다. 그 중에는 alert, confirm 등의 경고창을 뜨게 하는 명령이 실행되지 않는 것 등이 있습니다.
이러한 alert 등의 자바스크립트 코드가 작성되었을 때 해야할 동작은 네이티브 앱에서 수동으로 구현해야 합니다.
Alert
먼저 alert을 구현하는 방법에 대해 알아보겠습니다.
위의 extension 안에 아래 코드를 작성합니다. (runJavaScriptAlertPanelWithMessage)
1
2
3
4
5
6
7
8
9
10
11
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let alert = UIAlertController(title: "Alert", message: message, preferredStyle: .alert)
let alertAction = UIAlertAction(title: "확인", style: .default, handler: {_ in
completionHandler()
})
alert.addAction(alertAction)
DispatchQueue.main.async {
self.present(alert, animated: true, completion: nil)
}
}
여기서 message, completeHandler 변수를 사용해서 얼럿 띄우는 것을 구현해야 합니다. message는 자바스크립트의 alert("...") 에 작성된 메시지이고, completeHandler는 작업을 완료하는 콜백 함수입니다. 이 변수들을 사용해 일반적인 iOS의 얼럿 형태로 코드를 작성했습니다.
그리고 자바스크립트 부분에 다음 코드를 작성하면 얼럿창이 뜨는 것을 확인할 수 있습니다.
1
alert("얼럿이 왜 안돼?")
자바스크립트의 경고창으로는 alert외에 confirm(확인/취소), prompt(필드에 값을 입력)이 있습니다. 이것들도 위의 방법으로 구현해보도록 하겠습니다.
Confirm
confirm (runJavaScriptConfirmPanelWithMessage)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
let alert = UIAlertController(title: "Confirm", message: message, preferredStyle: .alert)
let noAction = UIAlertAction(title: "아니오", style: .default) { _ in
completionHandler(false)
}
let yesAction = UIAlertAction(title: "예", style: .default) { _ in
completionHandler(true)
}
alert.addAction(noAction)
alert.addAction(yesAction)
DispatchQueue.main.async {
self.present(alert, animated: true, completion: nil)
}
}
앞의 alert과의 차이점은 completionHandler의 파라미터에 Bool 값이 들어가서 true/false로 예/아니오를 구현하는 데에 있습니다.
자바스크립트를 작성합니다.
1
2
3
4
let isConfirm = confirm("승낙하시겠습니까?")
if(isConfirm) {
document.getElementById("title").textContent = "Confirm YES"
}
아니오 버튼을 누르면 아무 변화가 없고, 예 버튼을 누르면 위와 같이 제목이 바뀌는 것을 볼 수 있습니다.
Prompt
prompt (runJavaScriptTextInputPanelWithPrompt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
let alert = UIAlertController(title: "Prompt", message: "메시지를 입력하세요.", preferredStyle: .alert)
alert.addTextField { textField in
textField.placeholder = defaultText
}
let okAction = UIAlertAction(title: "OK", style: .default) { _ in
if let text = alert.textFields?[0].text {
completionHandler(text != "" ? text : defaultText)
} else {
completionHandler(defaultText)
}
}
alert.addAction(okAction)
DispatchQueue.main.async {
self.present(alert, animated: true, completion: nil)
}
}
text 또는 defaultText에서 메시지를 받으면, 메시지를 원문 또는 가공하여 completHandlert(text)으로 보내면 자바스크립트가 네이티브 앱으로부터 메시지를 받는 형식입니다.
자바스크립트를 작성합니다.
1
2
const promptStr = prompt("prompt", "기본값")
document.getElementById("title").textContent = promptStr
동작 화면
위와 같이 입력값에 따라 제목이 바뀌는 것을 볼 수 있습니다.





