Skip to content

Commit 589dc2a

Browse files
committed
Using Base class in UIWebView
1 parent b318263 commit 589dc2a

5 files changed

Lines changed: 36 additions & 185 deletions

File tree

WebViewJavascriptBridge/WKWebViewJavascriptBridge.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
#if defined(supportsWKWebKit )
1313

1414
#import <Foundation/Foundation.h>
15-
1615
#import <WebKit/WebKit.h>
16+
1717
typedef void (^WVJBResponseCallback)(id responseData);
1818
typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback);
1919

@@ -32,9 +32,6 @@ typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback);
3232
- (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback;
3333
- (void)reset;
3434

35-
// delegate method
36-
- (void) _evaluateJavascript:(NSString*)javascriptCommand;
37-
3835
@end
3936

4037
#endif

WebViewJavascriptBridge/WKWebViewJavascriptBridge.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ @implementation WKWebViewJavascriptBridge {
1818
WebViewJavascriptBridgeBase *_base;
1919
}
2020

21-
//@synthesize delegate;
22-
2321
/* API
2422
*****/
2523

@@ -165,9 +163,11 @@ - (void)webView:(WKWebView *)webView
165163
}
166164
}
167165

168-
- (void) _evaluateJavascript:(NSString*)javascriptCommand
166+
- (NSString*) _evaluateJavascript:(NSString*)javascriptCommand
169167
{
168+
NSLog(@"----- EVALUATING");
170169
[_webView evaluateJavaScript:javascriptCommand completionHandler:nil];
170+
return NULL;
171171
}
172172

173173

WebViewJavascriptBridge/WebViewJavascriptBridge.m

Lines changed: 19 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
#import "WebViewJavascriptBridge.h"
10+
#import "WebViewJavascriptBridgeBase.h"
1011

1112
#if __has_feature(objc_arc_weak)
1213
#define WVJB_WEAK __weak
@@ -19,14 +20,8 @@
1920
@implementation WebViewJavascriptBridge {
2021
WVJB_WEAK WVJB_WEBVIEW_TYPE* _webView;
2122
WVJB_WEAK id _webViewDelegate;
22-
NSMutableArray* _startupMessageQueue;
23-
NSMutableDictionary* _responseCallbacks;
24-
NSMutableDictionary* _messageHandlers;
2523
long _uniqueId;
26-
WVJBHandler _messageHandler;
27-
28-
NSBundle *_resourceBundle;
29-
24+
WebViewJavascriptBridgeBase *_base;
3025
#if defined WVJB_PLATFORM_IOS
3126
NSUInteger _numRequestsLoading;
3227
#endif
@@ -36,8 +31,7 @@ @implementation WebViewJavascriptBridge {
3631
/* API
3732
*****/
3833

39-
static bool logging = false;
40-
+ (void)enableLogging { logging = true; }
34+
+ (void)enableLogging { [WebViewJavascriptBridgeBase enableLogging]; }
4135

4236
+ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView handler:(WVJBHandler)handler {
4337
return [self bridgeForWebView:webView webViewDelegate:nil handler:handler];
@@ -59,7 +53,7 @@ - (void)send:(id)data {
5953
}
6054

6155
- (void)send:(id)data responseCallback:(WVJBResponseCallback)responseCallback {
62-
[self _sendData:data responseCallback:responseCallback handlerName:nil];
56+
[_base _sendData:data responseCallback:responseCallback handlerName:nil];
6357
}
6458

6559
- (void)callHandler:(NSString *)handlerName {
@@ -71,162 +65,28 @@ - (void)callHandler:(NSString *)handlerName data:(id)data {
7165
}
7266

7367
- (void)callHandler:(NSString *)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback {
74-
[self _sendData:data responseCallback:responseCallback handlerName:handlerName];
68+
[_base _sendData:data responseCallback:responseCallback handlerName:handlerName];
7569
}
7670

7771
- (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler {
78-
_messageHandlers[handlerName] = [handler copy];
72+
_base.messageHandlers[handlerName] = [handler copy];
7973
}
8074

8175
/* Platform agnostic internals
8276
*****************************/
8377

84-
- (id)init {
85-
if (self = [super init]) {
86-
_startupMessageQueue = [NSMutableArray array];
87-
_responseCallbacks = [NSMutableDictionary dictionary];
88-
_uniqueId = 0;
89-
}
90-
return self;
91-
}
92-
9378
- (void)dealloc {
9479
[self _platformSpecificDealloc];
95-
80+
_base = nil;
9681
_webView = nil;
9782
_webViewDelegate = nil;
98-
_startupMessageQueue = nil;
99-
_responseCallbacks = nil;
100-
_messageHandlers = nil;
101-
_messageHandler = nil;
102-
}
103-
104-
- (void)_sendData:(id)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName {
105-
NSMutableDictionary* message = [NSMutableDictionary dictionary];
106-
107-
if (data) {
108-
message[@"data"] = data;
109-
}
110-
111-
if (responseCallback) {
112-
NSString* callbackId = [NSString stringWithFormat:@"objc_cb_%ld", ++_uniqueId];
113-
_responseCallbacks[callbackId] = [responseCallback copy];
114-
message[@"callbackId"] = callbackId;
115-
}
116-
117-
if (handlerName) {
118-
message[@"handlerName"] = handlerName;
119-
}
120-
[self _queueMessage:message];
121-
}
122-
123-
- (void)_queueMessage:(WVJBMessage*)message {
124-
if (_startupMessageQueue) {
125-
[_startupMessageQueue addObject:message];
126-
} else {
127-
[self _dispatchMessage:message];
128-
}
129-
}
130-
131-
- (void)_dispatchMessage:(WVJBMessage*)message {
132-
NSString *messageJSON = [self _serializeMessage:message];
133-
[self _log:@"SEND" json:messageJSON];
134-
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"];
135-
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
136-
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\'" withString:@"\\\'"];
137-
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"];
138-
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r" withString:@"\\r"];
139-
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\f" withString:@"\\f"];
140-
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\u2028" withString:@"\\u2028"];
141-
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\u2029" withString:@"\\u2029"];
142-
143-
NSString* javascriptCommand = [NSString stringWithFormat:@"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON];
144-
if ([[NSThread currentThread] isMainThread]) {
145-
[_webView stringByEvaluatingJavaScriptFromString:javascriptCommand];
146-
} else {
147-
__strong WVJB_WEBVIEW_TYPE* strongWebView = _webView;
148-
dispatch_sync(dispatch_get_main_queue(), ^{
149-
[strongWebView stringByEvaluatingJavaScriptFromString:javascriptCommand];
150-
});
151-
}
152-
}
153-
154-
- (void)_flushMessageQueue {
155-
NSString *messageQueueString = [_webView stringByEvaluatingJavaScriptFromString:@"WebViewJavascriptBridge._fetchQueue();"];
156-
157-
id messages = [self _deserializeMessageJSON:messageQueueString];
158-
if (![messages isKindOfClass:[NSArray class]]) {
159-
NSLog(@"WebViewJavascriptBridge: WARNING: Invalid %@ received: %@", [messages class], messages);
160-
return;
161-
}
162-
for (WVJBMessage* message in messages) {
163-
if (![message isKindOfClass:[WVJBMessage class]]) {
164-
NSLog(@"WebViewJavascriptBridge: WARNING: Invalid %@ received: %@", [message class], message);
165-
continue;
166-
}
167-
[self _log:@"RCVD" json:message];
168-
169-
NSString* responseId = message[@"responseId"];
170-
if (responseId) {
171-
WVJBResponseCallback responseCallback = _responseCallbacks[responseId];
172-
responseCallback(message[@"responseData"]);
173-
[_responseCallbacks removeObjectForKey:responseId];
174-
} else {
175-
WVJBResponseCallback responseCallback = NULL;
176-
NSString* callbackId = message[@"callbackId"];
177-
if (callbackId) {
178-
responseCallback = ^(id responseData) {
179-
if (responseData == nil) {
180-
responseData = [NSNull null];
181-
}
182-
183-
WVJBMessage* msg = @{ @"responseId":callbackId, @"responseData":responseData };
184-
[self _queueMessage:msg];
185-
};
186-
} else {
187-
responseCallback = ^(id ignoreResponseData) {
188-
// Do nothing
189-
};
190-
}
191-
192-
WVJBHandler handler;
193-
if (message[@"handlerName"]) {
194-
handler = _messageHandlers[message[@"handlerName"]];
195-
} else {
196-
handler = _messageHandler;
197-
}
198-
199-
if (!handler) {
200-
[NSException raise:@"WVJBNoHandlerException" format:@"No handler for message from JS: %@", message];
201-
}
202-
203-
handler(message[@"data"], responseCallback);
204-
}
205-
}
206-
}
207-
208-
- (NSString *)_serializeMessage:(id)message {
209-
return [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:message options:0 error:nil] encoding:NSUTF8StringEncoding];
21083
}
21184

212-
- (NSArray*)_deserializeMessageJSON:(NSString *)messageJSON {
213-
return [NSJSONSerialization JSONObjectWithData:[messageJSON dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];
214-
}
215-
216-
- (void)_log:(NSString *)action json:(id)json {
217-
if (!logging) { return; }
218-
if (![json isKindOfClass:[NSString class]]) {
219-
json = [self _serializeMessage:json];
220-
}
221-
if ([json length] > 500) {
222-
NSLog(@"WVJB %@: %@ [...]", action, [json substringToIndex:500]);
223-
} else {
224-
NSLog(@"WVJB %@: %@", action, json);
225-
}
85+
- (NSString*) _evaluateJavascript:(NSString*)javascriptCommand
86+
{
87+
return [_webView stringByEvaluatingJavaScriptFromString:javascriptCommand];
22688
}
22789

228-
229-
23090
/* Platform specific internals: OSX
23191
**********************************/
23292
#if defined WVJB_PLATFORM_OSX
@@ -325,12 +185,9 @@ - (NSURLRequest *)webView:(WebView *)webView resource:(id)identifier willSendReq
325185
#elif defined WVJB_PLATFORM_IOS
326186

327187
- (void) _platformSpecificSetup:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(id<UIWebViewDelegate>)webViewDelegate handler:(WVJBHandler)messageHandler resourceBundle:(NSBundle*)bundle{
328-
_messageHandler = messageHandler;
329188
_webView = webView;
330189
_webViewDelegate = webViewDelegate;
331-
_messageHandlers = [NSMutableDictionary dictionary];
332-
_webView.delegate = self;
333-
_resourceBundle = bundle;
190+
_base = [[WebViewJavascriptBridgeBase alloc] initWithWebViewType:@"WebView" handler:(WVJBHandler)messageHandler resourceBundle:(NSBundle*)bundle];
334191
}
335192

336193
- (void) _platformSpecificDealloc {
@@ -342,19 +199,10 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView {
342199

343200
_numRequestsLoading--;
344201

345-
if (_numRequestsLoading == 0 && ![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) {
346-
NSBundle *bundle = _resourceBundle ? _resourceBundle : [NSBundle mainBundle];
347-
NSString *filePath = [bundle pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"];
348-
NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
349-
[webView stringByEvaluatingJavaScriptFromString:js];
350-
}
351-
352-
if (_startupMessageQueue) {
353-
for (id queuedMessage in _startupMessageQueue) {
354-
[self _dispatchMessage:queuedMessage];
355-
}
356-
_startupMessageQueue = nil;
202+
if (_numRequestsLoading == 0 && ![[webView stringByEvaluatingJavaScriptFromString:[_base webViewJavascriptCheckCommand]] isEqualToString:@"true"]) {
203+
[_base injectJavascriptFile:YES];
357204
}
205+
[_base dispatchStartUpMessageQueue];
358206

359207
__strong WVJB_WEBVIEW_DELEGATE_TYPE* strongDelegate = _webViewDelegate;
360208
if (strongDelegate && [strongDelegate respondsToSelector:@selector(webViewDidFinishLoad:)]) {
@@ -377,11 +225,12 @@ - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)
377225
if (webView != _webView) { return YES; }
378226
NSURL *url = [request URL];
379227
__strong WVJB_WEBVIEW_DELEGATE_TYPE* strongDelegate = _webViewDelegate;
380-
if ([[url scheme] isEqualToString:kCustomProtocolScheme]) {
381-
if ([[url host] isEqualToString:kQueueHasMessage]) {
382-
[self _flushMessageQueue];
228+
if ([_base correctProcotocolScheme:url]) {
229+
if ([_base correctHost:url]) {
230+
NSString *messageQueueString = [self _evaluateJavascript:[_base webViewJavascriptFetchQueyCommand]];
231+
[_base _flushMessageQueue:messageQueueString];
383232
} else {
384-
NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", kCustomProtocolScheme, [url path]);
233+
[_base logUnkownMessage:url];
385234
}
386235
return NO;
387236
} else if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) {

WebViewJavascriptBridge/WebViewJavascriptBridgeBase.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ typedef NSDictionary WVJBMessage;
1717

1818
// setup delegate
1919
@protocol WebViewJavascriptBridgeBaseDelegate <NSObject>
20-
- (void) _evaluateJavascript:(NSString*)javascriptCommand;
20+
- (NSString*) _evaluateJavascript:(NSString*)javascriptCommand;
2121
@end
2222

2323

@@ -48,6 +48,7 @@ typedef NSDictionary WVJBMessage;
4848
-(void) logUnkownMessage:(NSURL*)url;
4949
-(NSString *) webViewJavascriptCheckCommand;
5050
-(NSString *) webViewJavascriptFetchQueyCommand;
51+
- (void) dispatchStartUpMessageQueue;
5152

5253

5354
// probably dont need to be public

WebViewJavascriptBridge/WebViewJavascriptBridgeBase.m

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ -(id)initWithWebViewType:(NSString*)webViewType handler:(WVJBHandler)messageHand
2929
_resourceBundle = bundle;
3030
self.messageHandler = messageHandler;
3131
self.messageHandlers = [NSMutableDictionary dictionary];
32+
_uniqueId = 0;
3233
return(self);
3334
}
3435

@@ -177,17 +178,20 @@ - (void)injectJavascriptFile:(BOOL)shouldInject {
177178
NSString *filePath = [bundle pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"];
178179
NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
179180
[self _evaluateJavascript:js];
180-
181-
if (_startupMessageQueue) {
182-
for (id queuedMessage in _startupMessageQueue) {
183-
[self _dispatchMessage:queuedMessage];
184-
}
185-
_startupMessageQueue = nil;
186-
}
181+
[self dispatchStartUpMessageQueue];
187182
}
188183

189184
}
190185

186+
- (void) dispatchStartUpMessageQueue {
187+
if (_startupMessageQueue) {
188+
for (id queuedMessage in _startupMessageQueue) {
189+
[self _dispatchMessage:queuedMessage];
190+
}
191+
_startupMessageQueue = nil;
192+
}
193+
}
194+
191195
-(BOOL)correctProcotocolScheme:(NSURL*)url {
192196
if([[url scheme] isEqualToString:kCustomProtocolScheme]){
193197
return YES;

0 commit comments

Comments
 (0)