Skip to content

Commit 1dd9c74

Browse files
committed
Conflicts: WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m
2 parents beeb959 + 20ce1b0 commit 1dd9c74

File tree

6 files changed

+66
-35
lines changed

6 files changed

+66
-35
lines changed

WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@
22
#define kCustomProtocolScheme @"wvjbscheme"
33
#define kQueueHasMessage @"__WVJB_QUEUE_MESSAGE__"
44

5+
#if TARGET_OS_IPHONE && defined(__IPHONE_5_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0)
6+
#define WEAK_FALLBACK weak
7+
#elif TARGET_OS_MAC && defined(__MAC_10_7) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_7)
8+
#define WEAK_FALLBACK weak
9+
#else
10+
#define WEAK_FALLBACK unsafe_unretained
11+
#endif
12+
513
typedef void (^WVJBResponseCallback)(id responseData);
614
typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback);
715

816
@interface WebViewJavascriptBridgeAbstract : NSObject
917

10-
@property (nonatomic, strong) id webView;
11-
@property (nonatomic, strong) id webViewDelegate;
18+
@property (nonatomic, WEAK_FALLBACK) id webView;
19+
@property (nonatomic, WEAK_FALLBACK) id webViewDelegate;
1220
@property (nonatomic, strong) NSMutableArray *startupMessageQueue;
1321
@property (nonatomic, strong) NSMutableDictionary *responseCallbacks;
1422
@property (nonatomic, strong) NSMutableDictionary *messageHandlers;

WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,21 +79,23 @@ - (void)_dispatchMessage:(NSDictionary *)message {
7979
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"];
8080
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r" withString:@"\\r"];
8181
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\f" withString:@"\\f"];
82+
__strong typeof(self.webView) strongWebView = self.webView;
8283
if ([[NSThread currentThread] isMainThread]) {
83-
[self.webView performSelector:@selector(stringByEvaluatingJavaScriptFromString:)
84+
[strongWebView performSelector:@selector(stringByEvaluatingJavaScriptFromString:)
8485
withObject:[NSString stringWithFormat:
8586
@"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]];
8687
} else {
8788
dispatch_sync(dispatch_get_main_queue(), ^{
88-
[self.webView performSelector:@selector(stringByEvaluatingJavaScriptFromString:)
89+
[strongWebView performSelector:@selector(stringByEvaluatingJavaScriptFromString:)
8990
withObject:[NSString stringWithFormat:
9091
@"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]];
9192
});
9293
}
9394
}
9495

9596
- (void)_flushMessageQueue {
96-
NSString *messageQueueString = [self.webView performSelector:
97+
__strong typeof(self.webView) strongWebView = self.webView;
98+
NSString *messageQueueString = [strongWebView performSelector:
9799
@selector(stringByEvaluatingJavaScriptFromString:) withObject:@"WebViewJavascriptBridge._fetchQueue();"];
98100

99101
NSArray* messages = [messageQueueString componentsSeparatedByString:kMessageSeparator];
@@ -112,8 +114,8 @@ - (void)_flushMessageQueue {
112114
__block NSString* callbackId = message[@"callbackId"];
113115
if (callbackId) {
114116
responseCallback = ^(id responseData) {
115-
NSDictionary* message = @{ @"responseId":callbackId, @"responseData":responseData };
116-
[self _queueMessage:message];
117+
NSDictionary* msg = @{ @"responseId":callbackId, @"responseData":responseData };
118+
[self _queueMessage:msg];
117119
};
118120
} else {
119121
responseCallback = ^(id ignoreResponseData) {

WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
@interface WebViewJavascriptBridge : WebViewJavascriptBridgeAbstract
55

6-
@property (nonatomic, strong) WebView *webView;
7-
@property (nonatomic, strong) id webViewDelegate;
6+
@property (nonatomic, WEAK_FALLBACK) WebView *webView;
7+
@property (nonatomic, WEAK_FALLBACK) id webViewDelegate;
88

99
+ (instancetype)bridgeForWebView:(WebView*)webView handler:(WVJBHandler)handler;
1010
+ (instancetype)bridgeForWebView:(WebView*)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)handler;

WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ + (instancetype)bridgeForWebView:(WebView *)webView handler:(WVJBHandler)handler
77
}
88

99
+ (instancetype)bridgeForWebView:(WebView *)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler {
10-
WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init];
10+
WebViewJavascriptBridge* bridge = [[[self class] alloc] init];
1111
bridge.messageHandler = messageHandler;
1212
bridge.webView = webView;
1313
bridge.webViewDelegate = webViewDelegate;
@@ -21,14 +21,21 @@ + (instancetype)bridgeForWebView:(WebView *)webView webViewDelegate:(id)webViewD
2121
return bridge;
2222
}
2323

24+
- (void)dealloc;
25+
{
26+
self.webView.frameLoadDelegate = nil;
27+
self.webView.resourceLoadDelegate = nil;
28+
self.webView.policyDelegate = nil;
29+
}
30+
2431
- (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame
2532
{
2633
if (webView != self.webView) { return; }
2734

28-
if (![[self.webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) {
35+
if (![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) {
2936
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"];
3037
NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
31-
[self.webView stringByEvaluatingJavaScriptFromString:js];
38+
[webView stringByEvaluatingJavaScriptFromString:js];
3239
}
3340

3441
if (self.startupMessageQueue) {
@@ -38,48 +45,53 @@ - (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame
3845
self.startupMessageQueue = nil;
3946
}
4047

41-
if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)]) {
42-
[self.webViewDelegate webView:webView didFinishLoadForFrame:frame];
48+
__strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate;
49+
if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)]) {
50+
[strongDelegate webView:webView didFinishLoadForFrame:frame];
4351
}
4452
}
4553

4654
- (void)webView:(WebView *)webView didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame {
4755
if (webView != self.webView) { return; }
48-
if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) {
49-
[self.webViewDelegate webView:self.webView didFailLoadWithError:error forFrame:frame];
56+
__strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate;
57+
if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) {
58+
[strongDelegate webView:strongDelegate didFailLoadWithError:error forFrame:frame];
5059
}
5160
}
5261

5362
- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener
5463
{
5564
if (webView != self.webView) { [listener use]; }
5665
NSURL *url = [request URL];
66+
__strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate;
5767
if ([[url scheme] isEqualToString:kCustomProtocolScheme]) {
5868
if ([[url host] isEqualToString:kQueueHasMessage]) {
5969
[self _flushMessageQueue];
6070
} else {
6171
NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", kCustomProtocolScheme, [url path]);
6272
}
6373
[listener ignore];
64-
} else if ([self.webView resourceLoadDelegate]
65-
&& [self.webViewDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:request:frame:decisionListener:)]) {
66-
[self.webViewDelegate webView:webView decidePolicyForNavigationAction:actionInformation request:request frame:frame decisionListener:listener];
74+
} else if ([webView resourceLoadDelegate]
75+
&& [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:request:frame:decisionListener:)]) {
76+
[strongDelegate webView:webView decidePolicyForNavigationAction:actionInformation request:request frame:frame decisionListener:listener];
6777
} else {
6878
[listener use];
6979
}
7080
}
7181

7282
- (void)webView:(WebView *)webView didCommitLoadForFrame:(WebFrame *)frame {
7383
if (webView != self.webView) { return; }
74-
if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didCommitLoadForFrame:)]) {
75-
[self.webViewDelegate webView:webView didCommitLoadForFrame:frame];
84+
__strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate;
85+
if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didCommitLoadForFrame:)]) {
86+
[strongDelegate webView:webView didCommitLoadForFrame:frame];
7687
}
7788
}
7889

7990
- (NSURLRequest *)webView:(WebView *)webView resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource {
8091
if (webView != self.webView) { return request; }
81-
if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) {
82-
return [self.webViewDelegate webView:webView resource:identifier willSendRequest:request redirectResponse:redirectResponse fromDataSource:dataSource];
92+
__strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate;
93+
if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) {
94+
return [strongDelegate webView:webView resource:identifier willSendRequest:request redirectResponse:redirectResponse fromDataSource:dataSource];
8395
}
8496

8597
return request;

WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
@interface WebViewJavascriptBridge : WebViewJavascriptBridgeAbstract <UIWebViewDelegate>
55

6-
@property (nonatomic, strong) UIWebView *webView;
7-
@property (nonatomic, strong) id <UIWebViewDelegate> webViewDelegate;
6+
@property (nonatomic, WEAK_FALLBACK) UIWebView *webView;
7+
@property (nonatomic, WEAK_FALLBACK) id <UIWebViewDelegate> webViewDelegate;
88

99
+ (instancetype)bridgeForWebView:(UIWebView*)webView handler:(WVJBHandler)handler;
1010
+ (instancetype)bridgeForWebView:(UIWebView*)webView webViewDelegate:(id <UIWebViewDelegate>)webViewDelegate handler:(WVJBHandler)handler;

WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,18 @@ + (instancetype)bridgeForWebView:(UIWebView *)webView webViewDelegate:(id<UIWebV
2121
return bridge;
2222
}
2323

24+
- (void)dealloc;
25+
{
26+
self.webView.delegate = nil;
27+
}
28+
2429
- (void)webViewDidFinishLoad:(UIWebView *)webView {
2530
if (webView != self.webView) { return; }
2631

27-
if (![[self.webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) {
32+
if (![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) {
2833
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"];
2934
NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
30-
[self.webView stringByEvaluatingJavaScriptFromString:js];
35+
[webView stringByEvaluatingJavaScriptFromString:js];
3136
}
3237

3338
if (self.startupMessageQueue) {
@@ -37,39 +42,43 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView {
3742
self.startupMessageQueue = nil;
3843
}
3944

40-
if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webViewDidFinishLoad:)]) {
41-
[self.webViewDelegate webViewDidFinishLoad:webView];
45+
__strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate;
46+
if (strongDelegate && [strongDelegate respondsToSelector:@selector(webViewDidFinishLoad:)]) {
47+
[strongDelegate webViewDidFinishLoad:webView];
4248
}
4349
}
4450

4551
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
4652
if (webView != self.webView) { return; }
47-
if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) {
48-
[self.webViewDelegate webView:self.webView didFailLoadWithError:error];
53+
__strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate;
54+
if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) {
55+
[strongDelegate webView:webView didFailLoadWithError:error];
4956
}
5057
}
5158

5259
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
5360
if (webView != self.webView) { return YES; }
5461
NSURL *url = [request URL];
62+
__strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate;
5563
if ([[url scheme] isEqualToString:kCustomProtocolScheme]) {
5664
if ([[url host] isEqualToString:kQueueHasMessage]) {
5765
[self _flushMessageQueue];
5866
} else {
5967
NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", kCustomProtocolScheme, [url path]);
6068
}
6169
return NO;
62-
} else if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) {
63-
return [self.webViewDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
70+
} else if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) {
71+
return [strongDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
6472
} else {
6573
return YES;
6674
}
6775
}
6876

6977
- (void)webViewDidStartLoad:(UIWebView *)webView {
7078
if (webView != self.webView) { return; }
71-
if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
72-
[self.webViewDelegate webViewDidStartLoad:webView];
79+
__strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate;
80+
if (strongDelegate && [strongDelegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
81+
[strongDelegate webViewDidStartLoad:webView];
7382
}
7483
}
7584

0 commit comments

Comments
 (0)