BaseWebViewUIViewController.swift 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. //
  2. // BaseWebViewUIViewController.swift
  3. // O2Platform
  4. //
  5. // Created by 刘振兴 on 2016/10/11.
  6. // Copyright © 2016年 zoneland. All rights reserved.
  7. //
  8. import UIKit
  9. import WebKit
  10. import CocoaLumberjack
  11. protocol BaseWebViewUIViewControllerJSDelegate {
  12. func closeUIViewWindow()
  13. func actionBarLoaded(show: Bool)
  14. }
  15. protocol O2WKScriptMessageHandlerImplement {
  16. func userController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
  17. }
  18. open class BaseWebViewUIViewController: UIViewController {
  19. var webView:WKWebView!
  20. var delegate: BaseWebViewUIViewControllerJSDelegate?
  21. var o2WKScriptHandlers: [String : O2WKScriptMessageHandlerImplement] = [:]
  22. //定位用
  23. var locationCallBack: (String?) -> Void = {(result) in }
  24. private var locService: BMKLocationManager?
  25. private var searchAddress: BMKGeoCodeSearch?
  26. //继承的子类如果要添加MessageHandler必须在theWebView方法前使用
  27. func addScriptMessageHandler(key: String, handler: O2WKScriptMessageHandlerImplement) {
  28. o2WKScriptHandlers[key] = handler
  29. }
  30. open func theWebView(){
  31. let baseJsHandler = O2BaseJsMessageHandler(viewController: self)
  32. // bbs 回复
  33. addScriptMessageHandler(key: "ReplyAction", handler: baseJsHandler)
  34. // protal已经存在ActionBar
  35. addScriptMessageHandler(key: "actionBarLoaded", handler: baseJsHandler)
  36. // 打开工作 {"work":"", "workCompleted":"", "title":""}
  37. addScriptMessageHandler(key: "openO2Work", handler: baseJsHandler)
  38. // 4个分类 task taskCompleted read readCompleted
  39. addScriptMessageHandler(key: "openO2WorkSpace", handler: baseJsHandler)
  40. // 打开cms appId
  41. addScriptMessageHandler(key: "openO2CmsApplication", handler: baseJsHandler)
  42. // 打开cms docId docTitle
  43. addScriptMessageHandler(key: "openO2CmsDocument", handler: baseJsHandler)
  44. // 打开meeting
  45. addScriptMessageHandler(key: "openO2Meeting", handler: baseJsHandler)
  46. // 打开 calendar
  47. addScriptMessageHandler(key: "openO2Calendar", handler: baseJsHandler)
  48. // 打开扫一扫
  49. addScriptMessageHandler(key: "openScan", handler: baseJsHandler)
  50. addScriptMessageHandler(key: "openO2Alert", handler: baseJsHandler)
  51. // 打开钉钉
  52. addScriptMessageHandler(key: "openDingtalk", handler: baseJsHandler)
  53. // 关闭当前UIViewController
  54. addScriptMessageHandler(key:"closeNativeWindow", handler: baseJsHandler)
  55. // 上传图片到云盘,放入对应的业务区域
  56. addScriptMessageHandler(key: "uploadImage2FileStorage", handler: baseJsHandler)
  57. // 打印日志
  58. addScriptMessageHandler(key: "o2mLog", handler: baseJsHandler)
  59. //o2m.notification
  60. let o2Notification = O2JsApiNotification(viewController: self)
  61. addScriptMessageHandler(key: "o2mNotification", handler: o2Notification)
  62. //o2m.util
  63. let o2Util = O2JsApiUtil(viewController: self)
  64. addScriptMessageHandler(key: "o2mUtil", handler: o2Util)
  65. // o2m.biz
  66. let biz = O2JsApiBizUtil(viewController: self)
  67. addScriptMessageHandler(key: "o2mBiz", handler: biz)
  68. setupWebView()
  69. }
  70. public func setupWebView() {
  71. let userContentController = WKUserContentController()
  72. //cookie脚本
  73. if let cookies = HTTPCookieStorage.shared.cookies {
  74. let script = getJSCookiesString(cookies: cookies)
  75. let cookieScript = WKUserScript(source: script, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: false)
  76. userContentController.addUserScript(cookieScript)
  77. }
  78. // console.log 打印到ios log debug用
  79. let consoleLog = "console.log = (function(oriLogFunc){return function(str){window.webkit.messageHandlers.o2mLog.postMessage(str);oriLogFunc.call(console,str);} })(console.log);"
  80. let logScript = WKUserScript(source: consoleLog, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: false)
  81. userContentController.addUserScript(logScript)
  82. let webViewConfig = WKWebViewConfiguration()
  83. webViewConfig.userContentController = userContentController
  84. //加入js-app message handler
  85. for item in o2WKScriptHandlers {
  86. userContentController.add(self, name: item.key)
  87. }
  88. self.webView = WKWebView(frame: self.view.frame, configuration: webViewConfig)
  89. }
  90. ///Generates script to create given cookies
  91. public func getJSCookiesString(cookies: [HTTPCookie]) -> String {
  92. var result = ""
  93. let dateFormatter = DateFormatter()
  94. dateFormatter.timeZone = NSTimeZone(abbreviation: "UTC") as TimeZone?
  95. dateFormatter.dateFormat = "EEE, d MMM yyyy HH:mm:ss zzz"
  96. for cookie in cookies {
  97. result += "document.cookie='\(cookie.name)=\(cookie.value); domain=\(cookie.domain); path=\(cookie.path); "
  98. if let date = cookie.expiresDate {
  99. result += "expires=\(dateFormatter.string(from: date)); "
  100. }
  101. if (cookie.isSecure) {
  102. result += "secure; "
  103. }
  104. result += "'; "
  105. }
  106. return result
  107. }
  108. }
  109. extension BaseWebViewUIViewController: WKScriptMessageHandler {
  110. public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  111. let name = message.name
  112. if let handler = o2WKScriptHandlers[name] {
  113. handler.userController(userContentController, didReceive: message)
  114. }else {
  115. let err = "没有找到对应的key,key:\(name)"
  116. self.showError(title: err)
  117. }
  118. }
  119. }
  120. extension BaseWebViewUIViewController: BMKLocationManagerDelegate, BMKGeoCodeSearchDelegate {
  121. public func startLocation() {
  122. //开始定位
  123. locService = BMKLocationManager()
  124. if locService == nil {
  125. locService?.desiredAccuracy = kCLLocationAccuracyBest
  126. //设置返回位置的坐标系类型
  127. locService?.coordinateType = .BMK09LL
  128. //设置距离过滤参数
  129. locService?.distanceFilter = kCLDistanceFilterNone;
  130. //设置预期精度参数
  131. locService?.desiredAccuracy = kCLLocationAccuracyBest;
  132. //设置应用位置类型
  133. locService?.activityType = .automotiveNavigation
  134. //设置是否自动停止位置更新
  135. locService?.pausesLocationUpdatesAutomatically = false
  136. //定位返回geo地址信息
  137. locService?.locatingWithReGeocode = true
  138. //后台定位
  139. locService?.allowsBackgroundLocationUpdates = true
  140. }
  141. if searchAddress == nil {
  142. searchAddress = BMKGeoCodeSearch()
  143. }
  144. searchAddress?.delegate = self
  145. locService?.delegate = self
  146. locService?.startUpdatingLocation()
  147. }
  148. public func stopLocation() {
  149. locService?.stopUpdatingLocation()
  150. locService?.delegate = nil
  151. searchAddress?.delegate = nil
  152. }
  153. public func bmkLocationManager(_ manager: BMKLocationManager, didUpdate location: BMKLocation?, orError error: Error?) {
  154. if let loc = location?.location {
  155. DDLogDebug("当前位置,\(loc.coordinate.latitude),\(loc.coordinate.longitude)")
  156. //根据经纬度搜索到地址
  157. let re = BMKReverseGeoCodeSearchOption()
  158. re.location = CLLocationCoordinate2D(latitude: loc.coordinate.latitude, longitude: loc.coordinate.longitude)
  159. let _ = searchAddress?.reverseGeoCode(re)
  160. } else {
  161. DDLogError("没有获取到定位信息!!!!!")
  162. }
  163. }
  164. public func bmkLocationManager(_ manager: BMKLocationManager, didFailWithError error: Error?) {
  165. DDLogError("定位错误:\(String(describing: error?.localizedDescription))")
  166. }
  167. public func onGetReverseGeoCodeResult(_ searcher: BMKGeoCodeSearch?, result: BMKReverseGeoCodeSearchResult?, errorCode error: BMKSearchErrorCode) {
  168. //发送定位的实时位置及名称信息
  169. if let location = result?.location {
  170. var r = O2DeviceLocationResult()
  171. r.latitude = location.latitude
  172. r.longitude = location.longitude
  173. r.address = result?.address ?? "没有获取到地址!"
  174. locationCallBack(r.toJSONString())
  175. }else {
  176. var r = O2DeviceLocationResult()
  177. r.address = "没有获取到地址!"
  178. locationCallBack(r.toJSONString())
  179. DDLogError("搜索地址失败, \(error)")
  180. }
  181. //结束定位
  182. self.stopLocation()
  183. }
  184. public func onGetGeoCodeResult(_ searcher: BMKGeoCodeSearch!, result: BMKGeoCodeSearchResult!, errorCode error: BMKSearchErrorCode) {
  185. if Int(error.rawValue) == 0 {
  186. DDLogDebug("result \(String(describing: result))")
  187. } else {
  188. DDLogDebug("result error errorCode = \(Int(error.rawValue))")
  189. }
  190. }
  191. }