개발

Swift iOS WKWebView : WKUIDelegate 사용설정 (코드 부분)

소소ing 2020. 9. 22. 18:15
반응형

iOS WKWebView 에서 웹 페이지 대신 네이티브 사용자 인터페이스 요소를 표시할때 사용되는 WKUIDelegate를 사용해 봅시다.

 

해당 글에서 코드 부분은 파란색으로 표기 됩니다.

해당 글에서 중요 부분은 붉은색으로 표기 됩니다.

 

1. WKUIDelegate 란?

Apple 공식 도큐먼트 보러가기

위의 주소를 통해 확인해 보면 WKUIDelegate 클래스는 웹 페이지 대신 네이티브 사용자 인터페이스 요소를 표시하는 메서드를 제공된다고 말하고 있습니다.

 

1-1. WKUIDelegate를 사용하는 이유?

WKUIDelegate안에 선언된 딜리게이트 함수를 이용하여 서버에서 호출하는 alert 함수와 Confirm 등을 호출할 때 WebView 안에서 수신을 하게 되면 상단 부분 Web 주소가 노출되는 문제가 있습니다. 이때 딜리게이트 함수를 이용하여 원하는 화면으로 구성하여 출력할 수 있습니다.

 

2. "Swift iOS WKWebView : 기본 연동 (코드 부분)" 코드를 작성 한 후 붉은 부분을 추가 합니다.

[MainViewController.swift 파일 안]

// * WKWebView를 사용하기 위해서는 WebKit 모듈을 import 시켜야 합니다.

import WebKit

 

// * WKUIDelegate를 기입하여 해당 딜리게이트 사용을 알립니다.

class MainViewController: UIViewController, WKUIDelegate {

    // * WKWebView 객체 선언

    private var wkWebView: WKWebView? = nil

 

    override func viewDidLoad() {

        super.viewDidLoad()

        // * WKWebView 구성

        //    - 여기서는 self.view 화면 전체를 WKWebView로 구성하였습니다.

        self.wkWebView = WKWebView.init(frame: CGRect.init(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height))

 

        // * WKWebView WKUIDelegate 사용설정

        self.wkWebView?.uiDelegate = self       

 

        // * WKWebView 화면 비율 맞춤 설정

        self.wkWebView?.autoresizingMask = UIViewAutoresizing(rawValue: UIViewAutoresizing.RawValue(UInt8(UIViewAutoresizing.flexibleWidth.rawValue) | UInt8(UIViewAutoresizing.flexibleHeight.rawValue)))

 

        // * WKWebView 여백 및 배경 부분 색 투명하게 변경

        self.wkWebView?.backgroundColor = UIColor.clear

        self.wkWebView?.isOpaque = false

        self.wkWebView?.loadHTMLString("<body style=\"background-color: transparent\">", baseURL: nil)

   

         // * WKWebView에 로딩할 URL 전달

         //    - 캐시 기본 정책 사용, 타임아웃은 10초로 지정하였습니다.

         let request: URLRequest = URLRequest.init(url: NSURL.init(string: "<URL 입력>")! as URL, cachePolicy: URLRequest.CachePolicy.useProtocolCachePolicy, timeoutInterval: 10)

         self.wkWebView?.load(request)

 

          // * WKWebView 화면에 표시 

          self.view?.addSubview(self.wkWebView!)

    }

   

    

    // * WKWebView 웹보기가 탐색을 위한 필요 함수

    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView?

    {

       // * targetFrame의 mainframe이 nil일 경우 request를 로드합니다.

        if navigationAction.targetFrame?.isMainFrame == nil {

            webView.load(navigationAction.request)

        }

        return nil

    }

    

    // * WKWebView JavaScript alert 함수 호출 시 호출 이벤트를 수신하는 함수

    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,  completionHandler: @escaping () -> Void) {

       // * 전달 받은 message로 팝업 제목에 도메인 주소가 보이지 않도록 UIAlertController를 앱에서 호출하는 부분입니다.

        let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert)

        let ac = UIAlertAction(title: "OK", style: .default, handler: { action in

            completionHandler()

        })

       // * 만약 버튼의 색을 변경하고 싶다면 아래 구문을 추가 합니다.

        ac.setValue(UIColor.red, forKey: "titleTextColor")

        alertController.addAction(ac)

        self.present(alertController, animated: true, completion: nil)

    }

 

   // * WKWebView JavaScript confirm 함수 호출 시 호출 이벤트를 수신하는 함수

   func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {

       // * 전달 받은 message로 팝업 제목에 도메인 주소가 보이지 않도록 UIAlertController를 앱에서 호출하는 부분입니다.

        let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert)

        let ac = UIAlertAction(title: "OK", style: .default, handler: { action in

            completionHandler(true)

        })

        ac.setValue(UIColor.red, forKey: "titleTextColor")

        alertController.addAction(ac)

        let ac2 = UIAlertAction(title: "NO", style: .cancel, handler: { action in

            completionHandler(false)

        })

        ac2.setValue(UIColor.darkGray, forKey: "titleTextColor")

        alertController.addAction(ac2)            

        self.present(alertController, animated: true, completion: nil)

    }

 

   // * WKWebView JavaScript TextInputPanel 이벤트를 처리하는 함수

   func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {

        // * 전달 받은 message로 팝업 제목에 도메인 주소가 보이지 않도록 UIAlertController를 앱에서 호출하는 부분입니다.

        let alertController = UIAlertController(title:"", message: prompt, preferredStyle: .alert)

        alertController.addTextField { (textField) in

            textField.text = defaultText

        }

    

        let ac = UIAlertAction(title: Value.sharedInstance().userDefault?.object(forKey: UD_POP_LANG_OK) as! String? ?? MB_OK_en, style: .default, handler: { action in

            if let text = alertController.textFields?.first?.text {

                completionHandler(text)

            } else {

                completionHandler(defaultText)

            }

        })

        ac.setValue(UIColor.red, forKey: "titleTextColor")

        alertController.addAction(ac)

 

        let ac2 = UIAlertAction(title: Value.sharedInstance().userDefault?.object(forKey: UD_POP_LANG_NO) as! String? ?? MB_NO_en, style: .cancel, handler: { action in

            completionHandler(nil)

        })

        ac2.setValue(UIColor.darkGray, forKey: "titleTextColor")

        alertController.addAction(ac2)

        self.present(alertController, animated: true, completion: nil)

    }

}

반응형