Skip to content

Commit 8b1d103

Browse files
committed
Merge pull request marcuswestin#2 from psineur/noARC-and-multipleWebViews-support
Make jsBridge noARC & multiple webViews-compatible, improve interface.
2 parents 0e3cc42 + 7e70480 commit 8b1d103

File tree

4 files changed

+67
-38
lines changed

4 files changed

+67
-38
lines changed

WebViewJavascriptBridge.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
2C1E9EA314099B4600C5C30E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C1E9EA214099B4600C5C30E /* Foundation.framework */; };
1212
2C1E9EA914099B4600C5C30E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2C1E9EA714099B4600C5C30E /* InfoPlist.strings */; };
1313
2C1E9EAB14099B4600C5C30E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1E9EAA14099B4600C5C30E /* main.m */; };
14-
2C1E9EB814099BC900C5C30E /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1E9EB714099BC900C5C30E /* WebViewJavascriptBridge.m */; };
14+
2C1E9EB814099BC900C5C30E /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1E9EB714099BC900C5C30E /* WebViewJavascriptBridge.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
1515
2C6D2131143017AF0069FA34 /* ExampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C6D2130143017AF0069FA34 /* ExampleAppDelegate.m */; };
1616
/* End PBXBuildFile section */
1717

WebViewJavascriptBridge/Classes/WebViewJavascriptBridge.h

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,28 @@
22

33
@protocol WebViewJavascriptBridgeDelegate <NSObject>
44

5-
- (void) handleMessage:(NSString*) message;
5+
- (void) handleMessage:(NSString*) message fromWebView: (UIWebView *)theWebView;
66

77
@end
88

99
@interface WebViewJavascriptBridge : NSObject <UIWebViewDelegate> {
10-
id <WebViewJavascriptBridgeDelegate> delegate;
10+
id <WebViewJavascriptBridgeDelegate> _delegate;
11+
NSMutableArray *_startupMessageQueue;
1112
}
1213

13-
@property (nonatomic, strong) id <WebViewJavascriptBridgeDelegate> delegate;
14-
@property (nonatomic, retain) UIWebView* webView;
15-
@property (nonatomic, strong) NSMutableArray* startupMessageQueue;
14+
/** Delegate to receive messages from javascript. */
15+
@property (readwrite, assign) id <WebViewJavascriptBridgeDelegate> delegate;
1616

17-
+ (id) createWithDelegate:(id <WebViewJavascriptBridgeDelegate>) delegate;
17+
/** Creates & returns new autoreleased javascript Bridge with no delegate set. */
18+
+ (id) javascriptBridge;
1819

19-
- (void) sendMessage:(NSString*) message;
20-
21-
- (void) _flushMessageQueue;
22-
- (void) _doSendMessage:(NSString*)message;
20+
/** Sends message to given webView. You need to integrate javascript bridge into
21+
* this view before by calling WebViewJavascriptBridge#webViewDidFinishLoad: with that view.
22+
*
23+
* You can call this method before calling webViewDidFinishLoad: , than all messages
24+
* will be accumulated in _startupMessageQueue & sended to webView, provided by first
25+
* webViewDidFinishLoad: call.
26+
*/
27+
- (void) sendMessage:(NSString*) message toWebView:(UIWebView *) theWebView;
2328

2429
@end

WebViewJavascriptBridge/Classes/WebViewJavascriptBridge.m

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,59 @@
11
#import "WebViewJavascriptBridge.h"
22

3+
@interface WebViewJavascriptBridge ()
4+
5+
@property (readwrite,retain) NSMutableArray* startupMessageQueue;
6+
7+
- (void) _flushMessageQueueFromWebView: (UIWebView *) theWebView;
8+
- (void) _doSendMessage:(NSString*)message toWebView:(UIWebView *) theWebView;
9+
10+
@end
11+
312
@implementation WebViewJavascriptBridge
413

5-
@synthesize delegate;
6-
@synthesize webView;
7-
@synthesize startupMessageQueue;
14+
@synthesize delegate = _delegate;
15+
@synthesize startupMessageQueue = _startupMessageQueue;
816

917
static NSString* MESSAGE_SEPERATOR = @"__wvjb_sep__";
1018
static NSString* CUSTOM_PROTOCOL_SCHEME = @"webviewjavascriptbridge";
1119
static NSString* QUEUE_HAS_MESSAGE = @"queuehasmessage";
1220

13-
+ (id) createWithDelegate:(id <WebViewJavascriptBridgeDelegate>) delegate {
14-
WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init];
15-
bridge.delegate = delegate;
16-
bridge.startupMessageQueue = [[NSMutableArray alloc] init];
17-
return bridge;
21+
+ (id) javascriptBridge
22+
{
23+
return [[[self alloc] init] autorelease];
24+
}
25+
26+
- (id) init
27+
{
28+
if ( (self = [super init]) )
29+
{
30+
self.startupMessageQueue = [[NSMutableArray new] autorelease];
31+
}
32+
33+
return self;
34+
}
35+
36+
- (void) dealloc
37+
{
38+
self.delegate = nil;
39+
self.startupMessageQueue = nil;
40+
41+
[super dealloc];
1842
}
1943

20-
- (void)sendMessage:(NSString *)message {
21-
if (startupMessageQueue) { [startupMessageQueue addObject:message]; }
22-
else { [self _doSendMessage:message]; }
44+
- (void)sendMessage:(NSString *)message toWebView: (UIWebView *) theWebView {
45+
if (self.startupMessageQueue) { [self.startupMessageQueue addObject:message]; }
46+
else { [self _doSendMessage:message toWebView: theWebView]; }
2347
}
2448

25-
- (void)_doSendMessage:(NSString *)message {
49+
- (void)_doSendMessage:(NSString *)message toWebView: (UIWebView *) aWebView {
2650
message = [message stringByReplacingOccurrencesOfString:@"\\n" withString:@"\\\\n"];
2751
message = [message stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"];
2852
message = [message stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
29-
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"WebViewJavascriptBridge._handleMessageFromObjC('%@');", message]];
53+
[aWebView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"WebViewJavascriptBridge._handleMessageFromObjC('%@');", message]];
3054
}
3155

3256
- (void)webViewDidFinishLoad:(UIWebView *)theWebView {
33-
webView = theWebView;
3457
NSString* js;
3558
js = [NSString stringWithFormat:@";(function() {"
3659
"if (window.WebViewJavascriptBridge) { return; };"
@@ -92,12 +115,12 @@ - (void)webViewDidFinishLoad:(UIWebView *)theWebView {
92115
CUSTOM_PROTOCOL_SCHEME,
93116
QUEUE_HAS_MESSAGE];
94117

95-
[webView stringByEvaluatingJavaScriptFromString:js];
118+
[theWebView stringByEvaluatingJavaScriptFromString:js];
96119

97-
for (id message in startupMessageQueue) {
98-
[self _doSendMessage:message];
120+
for (id message in self.startupMessageQueue) {
121+
[self _doSendMessage:message toWebView: theWebView];
99122
}
100-
startupMessageQueue = nil;
123+
self.startupMessageQueue = nil;
101124
}
102125

103126

@@ -106,19 +129,19 @@ - (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest
106129
if (![[url scheme] isEqualToString:CUSTOM_PROTOCOL_SCHEME]) { return YES; }
107130

108131
if ([[url host] isEqualToString:QUEUE_HAS_MESSAGE]) {
109-
[self _flushMessageQueue];
132+
[self _flushMessageQueueFromWebView: theWebView];
110133
} else {
111134
NSLog(@"WARNING: Received unknown WebViewJavascriptBridge command %@://%@", CUSTOM_PROTOCOL_SCHEME, [url path]);
112135
}
113136

114137
return NO;
115138
}
116139

117-
- (void) _flushMessageQueue {
118-
NSString* messageQueueString = [webView stringByEvaluatingJavaScriptFromString:@"WebViewJavascriptBridge._fetchQueue();"];
140+
- (void) _flushMessageQueueFromWebView: (UIWebView *) theWebView {
141+
NSString* messageQueueString = [theWebView stringByEvaluatingJavaScriptFromString:@"WebViewJavascriptBridge._fetchQueue();"];
119142
NSArray* messages = [messageQueueString componentsSeparatedByString:MESSAGE_SEPERATOR];
120143
for (id message in messages) {
121-
[delegate handleMessage:message];
144+
[self.delegate handleMessage:message fromWebView: theWebView];
122145
}
123146
}
124147

WebViewJavascriptBridge/ExampleAppDelegate.m

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,20 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
1414
webView = [[UIWebView alloc] initWithFrame:self.window.bounds];
1515
[self.window addSubview:webView];
1616

17-
javascriptBridge = [WebViewJavascriptBridge createWithDelegate:self];
17+
javascriptBridge = [WebViewJavascriptBridge javascriptBridge];
18+
javascriptBridge.delegate = self;
1819
webView.delegate = javascriptBridge;
1920

20-
[javascriptBridge sendMessage:@"HI"];
21+
[javascriptBridge sendMessage:@"HI" toWebView: webView];
2122

2223
[self loadExamplePage];
2324

24-
[javascriptBridge sendMessage:@"HI2"];
25+
[javascriptBridge sendMessage:@"HI2" toWebView: webView];
2526

2627
return YES;
2728
}
2829

29-
- (void) handleMessage:(NSString *)message {
30+
- (void) handleMessage:(NSString *)message fromWebView:(UIWebView *)theWebView {
3031
NSLog(@"ExampleWebViewJavascriptBridgeDelegate received message: %@", message);
3132
}
3233

@@ -54,7 +55,7 @@ - (void) loadExamplePage {
5455
}
5556

5657
- (void)applicationWillResignActive:(UIApplication *)application
57-
{
58+
{
5859
/*
5960
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
6061
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.

0 commit comments

Comments
 (0)