@@ -10,76 +10,76 @@ import WebKit
10
10
11
11
/// Bridge for WKWebView and JavaScript
12
12
open class Bridge : NSObject {
13
-
13
+
14
14
static let name : String = " pacific "
15
-
15
+
16
16
fileprivate static let callbackEventName = " PacificDidReceiveNativeCallback "
17
17
fileprivate static let postEventName = " PacificDidReceiveNativeBroadcast "
18
-
18
+
19
19
fileprivate enum MessageKey {
20
20
static let action = " action "
21
21
static let parameters = " parameters "
22
22
static let callback = " callback "
23
23
static let printable = " print "
24
24
}
25
-
25
+
26
26
public struct JSError {
27
27
public let code : Int
28
28
public let description : String
29
-
29
+
30
30
public init ( code: Int , description: String ) {
31
31
self . code = code
32
32
self . description = description
33
33
}
34
34
}
35
-
35
+
36
36
/// Used to callback to webpage whether a message from webpage was handled successful or encountered an error.
37
37
///
38
38
/// - success: The result of message was successful
39
39
///
40
40
/// - failure: Unable to handle the message, notify js with error by **Object Error** { code: Int, description: String}
41
41
///
42
42
public enum Results {
43
-
43
+
44
44
case success( [ String : Any ] ? )
45
-
45
+
46
46
case failure( JSError )
47
47
}
48
-
48
+
49
49
/// Bridge Callback to webpage
50
50
/// - Parameter results: Value pass to webpage
51
51
public typealias Callback = ( _ results: Results ) -> Void
52
-
52
+
53
53
/// Closure when js send message to native
54
54
/// - Parameter parameters: js parameters
55
55
/// - Parameter callback: callback func
56
56
public typealias Handler = ( _ parameters: [ String : Any ] ? , _ callback: @escaping Callback ) -> Void
57
-
57
+
58
58
public typealias DefaultHandler = ( _ name: String , _ parameters: [ String : Any ] ? , _ callback: @escaping Callback ) -> Void
59
-
59
+
60
60
private( set) var handlers = [ String: Handler] ( )
61
-
61
+
62
62
public var defaultHandler : DefaultHandler ?
63
-
63
+
64
64
fileprivate let configuration : WKWebViewConfiguration
65
65
fileprivate weak var webView : WKWebView ?
66
-
66
+
67
67
/// Print message body from webpage automatically.
68
68
public var printScriptMessageAutomatically = false
69
-
69
+
70
70
deinit {
71
71
configuration. removeObserver ( self , forKeyPath: #keyPath( WKWebViewConfiguration . userContentController) )
72
72
configuration. userContentController. removeScriptMessageHandler ( forName: Bridge . name)
73
73
}
74
-
74
+
75
75
fileprivate init ( webView: WKWebView ) {
76
76
self . webView = webView
77
77
self . configuration = webView. configuration
78
78
super. init ( )
79
79
configuration. addObserver ( self , forKeyPath: #keyPath( WKWebViewConfiguration . userContentController) , options: [ . new, . old] , context: nil )
80
80
configuration. userContentController. add ( self , name: Bridge . name)
81
81
}
82
-
82
+
83
83
/// Register to handle action
84
84
/// - Parameter handler: closure when handle message from webpage
85
85
/// - parameter action: name of action
@@ -95,13 +95,13 @@ open class Bridge: NSObject {
95
95
public func register( _ handler: @escaping Handler , for action: String ) {
96
96
handlers [ action] = handler
97
97
}
98
-
98
+
99
99
/// Unregister an action
100
100
/// - Parameters action: name of action
101
101
public func unregister( for action: String ) {
102
102
handlers [ action] = nil
103
103
}
104
-
104
+
105
105
/// send action to webpage
106
106
/// - Parameter action: action listened by js `window.bridge.on(**action**, handler)`
107
107
/// - Parameter parameters: parameters pass to js
@@ -114,16 +114,16 @@ open class Bridge: NSObject {
114
114
guard let webView = webView else { return }
115
115
webView. st_dispatchBridgeEvent ( Bridge . postEventName, parameters: [ " name " : action] , results: . success( parameters) , completionHandler: nil )
116
116
}
117
-
117
+
118
118
/// Evaluates the given JavaScript string.
119
119
/// - Parameter javaScriptString: The JavaScript string to evaluate.
120
120
/// - Parameter completion: A block to invoke when script evaluation completes or fails.
121
121
public func evaluate( _ javaScriptString: String , completion: ( ( Any ? , Error ? ) -> Void ) ? = nil ) {
122
122
guard let webView = webView else { return }
123
123
webView. evaluateJavaScript ( javaScriptString, completionHandler: completion)
124
124
}
125
-
126
- open override func observeValue( forKeyPath keyPath: String ? , of object: Any ? , change: [ NSKeyValueChangeKey : Any ] ? , context: UnsafeMutableRawPointer ? ) {
125
+
126
+ open override func observeValue( forKeyPath keyPath: String ? , of object: Any ? , change: [ NSKeyValueChangeKey : Any ] ? , context: UnsafeMutableRawPointer ? ) {
127
127
if let obj = object as? WKWebViewConfiguration , let kp = keyPath, obj == configuration && kp == #keyPath( WKWebViewConfiguration . userContentController) {
128
128
if let change = change {
129
129
if let oldContentController = change [ . oldKey] as? WKUserContentController {
@@ -138,7 +138,7 @@ open class Bridge: NSObject {
138
138
}
139
139
140
140
extension Bridge : WKScriptMessageHandler {
141
-
141
+
142
142
/*! @abstract Invoked when a script message is received from a webpage.
143
143
@param userContentController The user content controller invoking the
144
144
delegate method.
@@ -171,7 +171,7 @@ extension Bridge: WKScriptMessageHandler {
171
171
}
172
172
return
173
173
}
174
-
174
+
175
175
if let callbackID = ( body [ MessageKey . callback] as? NSNumber ) {
176
176
handler ( body [ MessageKey . parameters] as? [ String : Any ] ) { [ weak self] ( results) in
177
177
guard let strongSelf = self else {
@@ -190,11 +190,11 @@ extension Bridge: WKScriptMessageHandler {
190
190
}
191
191
192
192
public extension WKWebView {
193
-
193
+
194
194
private struct STPrivateStatic {
195
195
fileprivate static var bridgeKey = " STPrivateStatic.bridgeKey "
196
196
}
197
-
197
+
198
198
/// Bridge for WKWebView and JavaScript. Initialize `lazy`
199
199
var bridge : Bridge {
200
200
if let bridge = objc_getAssociatedObject ( self , & STPrivateStatic. bridgeKey) as? Bridge {
@@ -204,7 +204,7 @@ public extension WKWebView {
204
204
objc_setAssociatedObject ( self , & STPrivateStatic. bridgeKey, bridge, . OBJC_ASSOCIATION_RETAIN_NONATOMIC)
205
205
return bridge
206
206
}
207
-
207
+
208
208
/// Remove Bridge And Reset, All the handlers will be removed
209
209
func removeBridge( ) {
210
210
if let bridge = objc_getAssociatedObject ( self , & STPrivateStatic. bridgeKey) as? Bridge {
@@ -216,12 +216,12 @@ public extension WKWebView {
216
216
}
217
217
218
218
fileprivate extension WKWebView {
219
-
219
+
220
220
func st_dispatchBridgeEvent( _ eventName: String ,
221
221
parameters: [ String : Any ] ,
222
222
results: Bridge . Results ,
223
223
completionHandler: ( ( Any ? , Error ? ) -> Void ) ? = nil ) {
224
-
224
+
225
225
var eventDetail : [ String : Any ] = parameters
226
226
switch results {
227
227
case . failure( let error) :
@@ -234,7 +234,7 @@ fileprivate extension WKWebView {
234
234
if
235
235
let _data = try ? JSONSerialization . data ( withJSONObject: eventBody, options: JSONSerialization . WritingOptions ( ) ) ,
236
236
let eventString = String ( data: _data, encoding: . utf8) {
237
-
237
+
238
238
jsString = " (function() { var event = new CustomEvent(' \( eventName) ', \( eventString) ); document.dispatchEvent(event)}()); "
239
239
} else {
240
240
// When JSON Not Serializable, Invoke with Default Parameters
0 commit comments