ExtraWebViewController.swift 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. //
  2. // ExtraWebViewControllerSwift.swift
  3. // MCPlus
  4. //
  5. // Created by seo ha on 15/02/2019.
  6. // Copyright © 2019 KangSH. All rights reserved.
  7. //
  8. import Foundation
  9. import UIKit
  10. import WebKit
  11. class ExtraWebViewController: UIViewController {
  12. @IBOutlet weak var webView:WKWebView!{
  13. didSet{
  14. webView.uiDelegate = self
  15. webView.navigationDelegate = self
  16. webView.configuration.userContentController.add(self, name: "mCarePlus")
  17. webView.configuration.suppressesIncrementalRendering = false // 데이터를 모두 받아야만 화면이 보여지게 하는 옵션
  18. var scriptContent = "var meta = document.createElement('meta');"
  19. scriptContent += "meta.name='viewport';"
  20. scriptContent += "meta.content='width=device-width';"
  21. scriptContent += "document.getElementsByTagName('head')[0].appendChild(meta);"
  22. webView.evaluateJavaScript(scriptContent, completionHandler: nil)
  23. webView.evaluateJavaScript("navigator.userAgent") { [weak webView](result, error) in
  24. if let userAgent = result as? String{
  25. webView?.customUserAgent = userAgent.appending("/mCarePlus")
  26. }
  27. }
  28. guard let url = URL(string: url ?? "") else {
  29. return
  30. }
  31. let request = URLRequest(url: url)
  32. webView.load(request)
  33. webView.isUserInteractionEnabled = true
  34. webView.scrollView.bounces = true
  35. webView.scrollView.isScrollEnabled = true
  36. }
  37. }
  38. @IBOutlet weak var menuBar:UIToolbar!
  39. @IBOutlet weak var backward:UIBarButtonItem!{
  40. didSet{
  41. backward.action = #selector(actionBackward(_:))
  42. }
  43. }
  44. @IBOutlet weak var forward:UIBarButtonItem!{
  45. didSet{
  46. forward.action = #selector(actionForward(_:))
  47. }
  48. }
  49. @IBOutlet weak var refresh:UIBarButtonItem!{
  50. didSet{
  51. refresh.action = #selector(actionRefresh(_:))
  52. }
  53. }
  54. @IBOutlet weak var close:UIBarButtonItem!{
  55. didSet{
  56. close.action = #selector(actionClose(_:))
  57. }
  58. }
  59. var url:String?
  60. }
  61. extension ExtraWebViewController{
  62. override func viewDidLoad() {
  63. super.viewDidLoad()
  64. webView.frame = self.view.frame
  65. }
  66. override func didReceiveMemoryWarning() {
  67. super.didReceiveMemoryWarning()
  68. }
  69. @objc func actionBackward(_ event:UIEvent){
  70. print("actionBackward")
  71. if self.webView.canGoBack{
  72. self.webView.goBack()
  73. }
  74. }
  75. @objc func actionForward(_ event:UIEvent){
  76. print("actionForward")
  77. if self.webView.canGoForward{
  78. self.webView.goForward()
  79. }
  80. }
  81. @objc func actionRefresh(_ event:UIEvent){
  82. print("actionRefresh")
  83. self.webView.reload()
  84. }
  85. @objc func actionClose(_ event:UIEvent){
  86. print("actionClose")
  87. self.dismiss(animated: true, completion: nil)
  88. }
  89. }
  90. extension ExtraWebViewController:WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler{
  91. func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping ((WKNavigationActionPolicy) -> Void)) {
  92. let request = navigationAction.request
  93. guard let url = request.url else {
  94. return
  95. }
  96. let absoluteString = url.absoluteString
  97. switch absoluteString {
  98. //메일
  99. case let variable where variable.hasPrefix("mailto:"):
  100. fallthrough
  101. //전화
  102. case let variable where variable.hasPrefix("tel:"):
  103. fallthrough
  104. //아이튠즈
  105. case let variable where variable.hasPrefix("https://itunes.apple.com/"):
  106. fallthrough
  107. //스토리링크
  108. case let variable where variable.hasPrefix("storylink://"):
  109. UIApplication.shared.open(url)
  110. decisionHandler(.cancel)
  111. //일반 웹호출
  112. case let variable where variable.hasPrefix("http://"):
  113. fallthrough
  114. case let variable where variable.hasPrefix("https://"):
  115. decisionHandler(.allow)
  116. default:
  117. decisionHandler(.cancel)
  118. }
  119. self.backward.tintColor = webView.canGoBack ? UIColor.white : UIColor.clear
  120. self.backward.isAccessibilityElement = webView.canGoBack
  121. self.forward.tintColor = webView.canGoForward ? UIColor.white : UIColor.clear
  122. self.forward.isAccessibilityElement = webView.canGoForward
  123. }
  124. func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
  125. if let urlResponse = navigationResponse.response as? HTTPURLResponse,
  126. let url = urlResponse.url,
  127. let allHeaderFields = urlResponse.allHeaderFields as? [String : String] {
  128. let cookies = HTTPCookie.cookies(withResponseHeaderFields: allHeaderFields, for: url)
  129. HTTPCookieStorage.shared.setCookies(cookies , for: url, mainDocumentURL: nil)
  130. decisionHandler(.allow)
  131. }
  132. }
  133. func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
  134. completionHandler: @escaping () -> Void) {
  135. self.showAlert("", message, "확인", nil, { (action) in
  136. completionHandler()
  137. })
  138. }
  139. func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
  140. completionHandler: @escaping (Bool) -> Void) {
  141. self.showAlert("", message, "확인", "취소", { (action) in
  142. completionHandler(true)
  143. },{ (action) in
  144. completionHandler(false)
  145. })
  146. }
  147. func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo,
  148. completionHandler: @escaping (String?) -> Void) {
  149. let alertController = UIAlertController(title: "", message: prompt, preferredStyle: .alert)
  150. alertController.addTextField { (textField) in
  151. textField.text = defaultText
  152. }
  153. alertController.addAction(UIAlertAction(title: "확인", style: .default, handler: { (action) in
  154. if let text = alertController.textFields?.first?.text {
  155. completionHandler(text)
  156. } else {
  157. completionHandler(defaultText)
  158. }
  159. }))
  160. alertController.addAction(UIAlertAction(title: "취소", style: .default, handler: { (action) in
  161. completionHandler(nil)
  162. }))
  163. self.present(alertController, animated: true, completion: nil)
  164. }
  165. func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
  166. let userController = WKUserContentController()
  167. configuration.preferences.javaScriptCanOpenWindowsAutomatically = true
  168. configuration.userContentController = userController
  169. let newWebView:WKWebView = {
  170. let webView = WKWebView(frame: webView.frame, configuration: configuration)
  171. webView.uiDelegate = self
  172. webView.navigationDelegate = self
  173. webView.frame.origin.y = 0
  174. webView.configuration.userContentController.add(self, name: "mCarePlus")
  175. webView.evaluateJavaScript("navigator.userAgent") { [weak webView](result, error) in
  176. if let userAgent = result as? String{
  177. webView?.customUserAgent = userAgent.appending("/mCarePlus")
  178. }
  179. }
  180. return webView
  181. }()
  182. let button:UIButton = {
  183. let button = UIButton(type: .system)
  184. button.isHidden = true
  185. button.frame = CGRect(x:(webView.frame.size.width) - 30, y:0, width: 30, height: 30)
  186. button.backgroundColor = UIColor.black
  187. button.layer.cornerRadius = 15
  188. button.setTitle("X", for: .normal)
  189. button.addTapGestureRecognizer(action: deleteSubWebView)
  190. return button
  191. }()
  192. webView.addSubview(newWebView)
  193. webView.addSubview(button)
  194. return newWebView
  195. }
  196. func deleteSubWebView(){
  197. for view in webView.subviews{
  198. view.removeFromSuperview()
  199. }
  200. }
  201. func webViewDidClose(_ webView: WKWebView) {
  202. for view in webView.subviews{
  203. view.removeFromSuperview()
  204. }
  205. webView.removeFromSuperview()
  206. }
  207. public func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
  208. // 중복적으로 리로드가 일어나지 않도록 처리 필요.
  209. webView.reload()
  210. }
  211. func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
  212. }
  213. func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  214. }
  215. }