나의 발자취
WebView: alert 만들기 (파일명: WebNativeCom) 본문
alert창의 경우 하나의 뷰를 더 사용하게 된다, iOS에서는 뷰가 하나이기 때문에, alert를 위한 뷰를 하나 더 만들어준다.
1. 확인 버튼 Action
extension ViewController: WKUIDelegate {
public func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
let action = UIAlertAction(title: "확인", style: .default) { _ in
completionHandler()
}
alert.addAction(action)
present(alert, animated: true)
}
}
마지막으로 Delegate 선언
// alert창을 위한 VC(아래 extension) Delegate
webView?.uiDelegate = self
2. Confirm/Cancel 버튼 Action
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
// (Bool) 이니까 action 두개
// true
let actionTrue = UIAlertAction(title: "확인", style: .default) { _ in
completionHandler(true)
}
alert.addAction(actionTrue)
// false
let actionFalse = UIAlertAction(title: "취소", style: .cancel) { _ in
completionHandler(false)
}
alert.addAction(actionFalse)
present(alert, animated: true)
}
3. 프롬프트창
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
let alert = UIAlertController(title: nil, message: prompt, preferredStyle: .alert)
alert.addTextField { textfield in
textfield.placeholder = defaultText
}
let action = UIAlertAction(title: "입력하세요", style: .default) { _ in
// FIXME: - 기분이 안좋음.
if let text1 = alert.textFields?[0] {
let text = text1.text == "" ? defaultText : text1.text
completionHandler(text)
} else {
completionHandler(defaultText)
}
}
alert.addAction(action)
present(alert, animated: true)
}
최종 코드
import UIKit
import WebKit
class ViewController: UIViewController {
var webView: WKWebView?
override func viewDidLoad() {
super.viewDidLoad()
let userContent = WKUserContentController()
userContent.add(self, name: "SendMessage")
userContent.add(self, name: "SayHello")
userContent.add(self, name: "SetUser")
let webViewConfig = WKWebViewConfiguration()
webViewConfig.userContentController = userContent
let frame = CGRect(origin: view.frame.origin, size: CGSize(width: view.frame.width, height: view.frame.height/3*2))
webView = WKWebView(frame: frame, configuration: webViewConfig)
view.addSubview(webView!)
// request 생성
guard let url = URL(string: "http://127.0.0.1:8080") else { return }
let request = URLRequest(url: url)
webView?.load(request)
// alert창을 위한 VC(아래 extension) Delegate
webView?.uiDelegate = self
}
// Add Buttons
@IBAction func action1(_ sender: Any) {
webView?.evaluateJavaScript("call_func1()")
}
@IBAction func action2(_ sender: Any) {
let name = "aespa"
webView?.evaluateJavaScript("call_func2('\(name)')")
}
@IBAction func action3(_ sender: Any) {
let info = ["phone": "010-1111-1111", "email": "a@a.com","name": "홍길동", "gender": "male"]
do {
// data 정렬화
let infoData: Data = try JSONSerialization.data(withJSONObject: info)
// data 인코딩
guard let encodedData = String(data: infoData, encoding: .utf8) else { return }
// JS function과 통신
webView?.evaluateJavaScript("call_func3('\(encodedData)')",
completionHandler: {result, error in
if let error {return}
guard let info = result as? [String:String] else {return}
print(info)
})
} catch {
print("error occured")
}
}
}
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
switch message.name {
case "SendMessage":
print("SendMessage")
print(message.body)
case "SayHello":
print("SayHello")
print(message.body)
case "SetUser":
print("SetUser")
print(message.body)
if let info = message.body as? [String:String] {
print(info["name"]!, info["email"]!, info["gender"]!)
}
default:
print("정의되지 않은 메시지")
}
}
}
extension ViewController: WKUIDelegate {
public func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
let action = UIAlertAction(title: "확인", style: .default) { _ in
completionHandler()
}
alert.addAction(action)
present(alert, animated: true)
}
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
// (Bool) 이니까 action 두개
// true
let actionTrue = UIAlertAction(title: "확인", style: .default) { _ in
completionHandler(true)
}
alert.addAction(actionTrue)
// false
let actionFalse = UIAlertAction(title: "취소", style: .cancel) { _ in
completionHandler(false)
}
alert.addAction(actionFalse)
present(alert, animated: true)
}
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
let alert = UIAlertController(title: nil, message: prompt, preferredStyle: .alert)
alert.addTextField { textfield in
textfield.placeholder = defaultText
}
let action = UIAlertAction(title: "입력하세요", style: .default) { _ in
// FIXME: - 기분이 안좋음.
if let text1 = alert.textFields?[0] {
let text = text1.text == "" ? defaultText : text1.text
completionHandler(text)
} else {
completionHandler(defaultText)
}
}
alert.addAction(action)
present(alert, animated: true)
}
}
'앱 개발 > iOS' 카테고리의 다른 글
KakaoAPI를 활용한 BookSearch 앱 만들기 (2) (0) | 2024.09.09 |
---|---|
KakaoAPI를 활용한 BookSearch 앱 만들기 (1) (3) | 2024.09.06 |
Xcode 주석 종류 (0) | 2024.09.05 |
iOS WebKit: 웹뷰 frame 크기 조절, 버튼 넣기 (1) | 2024.09.05 |
iOS WebKit: Web <> App 통신하기 (4) | 2024.09.05 |
Comments