BaseWebViewUIViewController.swift 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. /// 设置 userAgent
  90. self.webView.evaluateJavaScript("navigator.userAgent") { (result, err) in
  91. if let ua = result as? String {
  92. self.webView.customUserAgent = "\(ua) o2oa"
  93. }
  94. }
  95. }
  96. ///Generates script to create given cookies
  97. public func getJSCookiesString(cookies: [HTTPCookie]) -> String {
  98. var result = ""
  99. let dateFormatter = DateFormatter()
  100. dateFormatter.timeZone = NSTimeZone(abbreviation: "UTC") as TimeZone?
  101. dateFormatter.dateFormat = "EEE, d MMM yyyy HH:mm:ss zzz"
  102. for cookie in cookies {
  103. result += "document.cookie='\(cookie.name)=\(cookie.value); domain=\(cookie.domain); path=\(cookie.path); "
  104. if let date = cookie.expiresDate {
  105. result += "expires=\(dateFormatter.string(from: date)); "
  106. }
  107. if (cookie.isSecure) {
  108. result += "secure; "
  109. }
  110. result += "'; "
  111. }
  112. return result
  113. }
  114. }
  115. extension BaseWebViewUIViewController: WKScriptMessageHandler {
  116. public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  117. let name = message.name
  118. if let handler = o2WKScriptHandlers[name] {
  119. handler.userController(userContentController, didReceive: message)
  120. }else {
  121. let err = "没有找到对应的key,key:\(name)"
  122. self.showError(title: err)
  123. }
  124. }
  125. }
  126. extension BaseWebViewUIViewController: BMKLocationManagerDelegate, BMKGeoCodeSearchDelegate {
  127. public func startLocation() {
  128. //开始定位
  129. locService = BMKLocationManager()
  130. if locService == nil {
  131. locService?.desiredAccuracy = kCLLocationAccuracyBest
  132. //设置返回位置的坐标系类型
  133. locService?.coordinateType = .BMK09LL
  134. //设置距离过滤参数
  135. locService?.distanceFilter = kCLDistanceFilterNone;
  136. //设置预期精度参数
  137. locService?.desiredAccuracy = kCLLocationAccuracyBest;
  138. //设置应用位置类型
  139. locService?.activityType = .automotiveNavigation
  140. //设置是否自动停止位置更新
  141. locService?.pausesLocationUpdatesAutomatically = false
  142. //定位返回geo地址信息
  143. locService?.locatingWithReGeocode = true
  144. //后台定位
  145. locService?.allowsBackgroundLocationUpdates = true
  146. }
  147. if searchAddress == nil {
  148. searchAddress = BMKGeoCodeSearch()
  149. }
  150. searchAddress?.delegate = self
  151. locService?.delegate = self
  152. locService?.startUpdatingLocation()
  153. }
  154. public func stopLocation() {
  155. locService?.stopUpdatingLocation()
  156. locService?.delegate = nil
  157. searchAddress?.delegate = nil
  158. }
  159. public func bmkLocationManager(_ manager: BMKLocationManager, didUpdate location: BMKLocation?, orError error: Error?) {
  160. if let loc = location?.location {
  161. DDLogDebug("当前位置,\(loc.coordinate.latitude),\(loc.coordinate.longitude)")
  162. //根据经纬度搜索到地址
  163. let re = BMKReverseGeoCodeSearchOption()
  164. re.location = CLLocationCoordinate2D(latitude: loc.coordinate.latitude, longitude: loc.coordinate.longitude)
  165. let _ = searchAddress?.reverseGeoCode(re)
  166. } else {
  167. DDLogError("没有获取到定位信息!!!!!")
  168. }
  169. }
  170. public func bmkLocationManager(_ manager: BMKLocationManager, didFailWithError error: Error?) {
  171. DDLogError("定位错误:\(String(describing: error?.localizedDescription))")
  172. }
  173. public func onGetReverseGeoCodeResult(_ searcher: BMKGeoCodeSearch?, result: BMKReverseGeoCodeSearchResult?, errorCode error: BMKSearchErrorCode) {
  174. //发送定位的实时位置及名称信息
  175. if let location = result?.location {
  176. var r = O2DeviceLocationResult()
  177. r.latitude = location.latitude
  178. r.longitude = location.longitude
  179. r.address = result?.address ?? "没有获取到地址!"
  180. locationCallBack(r.toJSONString())
  181. }else {
  182. var r = O2DeviceLocationResult()
  183. r.address = "没有获取到地址!"
  184. locationCallBack(r.toJSONString())
  185. DDLogError("搜索地址失败, \(error)")
  186. }
  187. //结束定位
  188. self.stopLocation()
  189. }
  190. public func onGetGeoCodeResult(_ searcher: BMKGeoCodeSearch!, result: BMKGeoCodeSearchResult!, errorCode error: BMKSearchErrorCode) {
  191. if Int(error.rawValue) == 0 {
  192. DDLogDebug("result \(String(describing: result))")
  193. } else {
  194. DDLogDebug("result error errorCode = \(Int(error.rawValue))")
  195. }
  196. }
  197. }