Skip to content

Commit a5d46b6

Browse files
committed
add WKWebViewJavascriptBridge and opz code
1 parent e6aeeb9 commit a5d46b6

2 files changed

Lines changed: 57 additions & 19 deletions

File tree

WKWebViewJavascriptBridge/WKWebViewJavascriptBridge.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,48 @@
77
//
88

99
import Foundation
10+
import WebKit
11+
12+
@available(iOS 9.0, *)
13+
public class WKWebViewJavascriptBridge: NSObject {
14+
private weak var webView: WKWebView!
15+
private var base: WKWebViewJavascriptBridgeBase!
16+
17+
public init(webView: WKWebView) {
18+
self.webView = webView
19+
super.init()
20+
}
21+
22+
public func reset() {
23+
base.reset()
24+
}
25+
26+
public func register(handlerName: String, handler: @escaping WKWebViewJavascriptBridgeBase.Handler) {
27+
base.messageHandlers[handlerName] = handler
28+
}
29+
30+
public func remove(handlerName: String) -> WKWebViewJavascriptBridgeBase.Handler? {
31+
return base.messageHandlers.removeValue(forKey: handlerName)
32+
}
33+
34+
public func call(handlerName: String, data: Any? = nil, callback: WKWebViewJavascriptBridgeBase.Callback? = nil) {
35+
base.send(handlerName: handlerName, data: data, callback: callback)
36+
}
37+
38+
func flushMessageQueue() {
39+
webView.evaluateJavaScript("WebViewJavascriptBridge._fetchQueue();") { (result, error) in
40+
if error != nil {
41+
print("WKWebViewJavascriptBridge: WARNING: Error when trying to fetch data from WKWebView: \(String(describing: error))")
42+
}
43+
44+
guard let resultStr = result as? String else { return }
45+
self.base.flush(messageQueueString: resultStr)
46+
}
47+
}
48+
}
49+
50+
extension WKWebViewJavascriptBridge: WKScriptMessageHandler {
51+
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
52+
self.flushMessageQueue()
53+
}
54+
}

WKWebViewJavascriptBridge/WKWebViewJavascriptBridgeBase.swift

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,26 @@ protocol WKWebViewJavascriptBridgeBaseDelegate: AnyObject {
1414
}
1515

1616
@available(iOS 9.0, *)
17-
class WKWebViewJavascriptBridgeBase: NSObject {
18-
typealias Callback = (_ responseData: Any?) -> Void
19-
typealias Handler = (_ parameters: [String: Any]?, _ callback: Callback?) -> Void
20-
typealias Message = [String: Any]
17+
public class WKWebViewJavascriptBridgeBase: NSObject {
18+
public typealias Callback = (_ responseData: Any?) -> Void
19+
public typealias Handler = (_ parameters: [String: Any]?, _ callback: Callback?) -> Void
20+
public typealias Message = [String: Any]
2121

2222
weak var delegate: WKWebViewJavascriptBridgeBaseDelegate?
2323
var startupMessageQueue = [Message]()
2424
var responseCallbacks = [String: Callback]()
2525
var messageHandlers = [String: Handler]()
2626
var uniqueId = 0
2727

28-
override init() {
29-
super.init()
30-
}
31-
3228
func reset() {
3329
self.startupMessageQueue = [Message]()
3430
self.responseCallbacks = [String: Callback]()
3531
self.uniqueId = 0
3632
}
3733

38-
func send(data: Any?, callback: Callback?, handlerName: String?) {
34+
func send(handlerName: String, data: Any?, callback: Callback?) {
3935
var message = [String: Any]()
36+
message["handlerName"] = handlerName
4037

4138
if data != nil {
4239
message["data"] = data
@@ -49,10 +46,6 @@ class WKWebViewJavascriptBridgeBase: NSObject {
4946
message["callbackID"] = callbackID
5047
}
5148

52-
if handlerName != nil {
53-
message["handlerName"] = handlerName
54-
}
55-
5649
self.queue(message: message)
5750
}
5851

@@ -99,15 +92,15 @@ class WKWebViewJavascriptBridgeBase: NSObject {
9992
}
10093

10194
// MARK: - Private
102-
fileprivate func queue(message: Message) {
95+
private func queue(message: Message) {
10396
if self.startupMessageQueue.isEmpty {
10497
self.dispatch(message: message)
10598
} else {
10699
self.startupMessageQueue.append(message)
107100
}
108101
}
109102

110-
fileprivate func dispatch(message: Message) {
103+
private func dispatch(message: Message) {
111104
guard var messageJSON = self.serialize(message: message, pretty: false) else {
112105
return
113106
}
@@ -121,7 +114,7 @@ class WKWebViewJavascriptBridgeBase: NSObject {
121114
// messageJSON = messageJSON.replacingOccurrences(of: "\u2028", with: "\\u2028")
122115
// messageJSON = messageJSON.replacingOccurrences(of: "\u2029", with: "\\u2029")
123116

124-
let javascriptCommand = "WebViewJavascriptBridge._handleMessageFromObjC('\(messageJSON)');"
117+
let javascriptCommand = "WebViewJavascriptBridge._handleMessageFromiOS('\(messageJSON)');"
125118
if Thread.current.isMainThread {
126119
self.delegate?.evaluateJavascript(javascript: javascriptCommand)
127120
} else {
@@ -132,7 +125,7 @@ class WKWebViewJavascriptBridgeBase: NSObject {
132125
}
133126

134127
// MARK: - JSON
135-
fileprivate func serialize(message: Message, pretty: Bool) -> String? {
128+
private func serialize(message: Message, pretty: Bool) -> String? {
136129
var result: String?
137130
do {
138131
let data = try JSONSerialization.data(withJSONObject: message, options: pretty ? .prettyPrinted : JSONSerialization.WritingOptions(rawValue: 0))
@@ -143,7 +136,7 @@ class WKWebViewJavascriptBridgeBase: NSObject {
143136
return result
144137
}
145138

146-
fileprivate func deserialize(messageJSON: String) -> [Message]? {
139+
private func deserialize(messageJSON: String) -> [Message]? {
147140
var result = [Message]()
148141
guard let data = messageJSON.data(using: .utf8) else {
149142
return nil
@@ -157,7 +150,7 @@ class WKWebViewJavascriptBridgeBase: NSObject {
157150
}
158151

159152
// MARK: - Log
160-
fileprivate func log<T>(_ message: T, file: String = #file, function: String = #function, line: Int = #line) {
153+
private func log<T>(_ message: T, file: String = #file, function: String = #function, line: Int = #line) {
161154
#if DEBUG
162155
let fileName = (file as NSString).lastPathComponent
163156
print("\(fileName):\(line) \(function) | \(message)")

0 commit comments

Comments
 (0)