From b1c921993ef4d27011d68540b2d104234596cf5f Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 1 Mar 2013 09:21:51 -0800 Subject: [PATCH 001/285] Put the handler name first, so that it shows up before the data in the log messages --- WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt b/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt index 26ee1d62..7936c0e8 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt @@ -37,7 +37,7 @@ } function callHandler(handlerName, data, responseCallback) { - _doSend({ data:data, handlerName:handlerName }, responseCallback) + _doSend({ handlerName:handlerName, data:data }, responseCallback) } function _doSend(message, responseCallback) { From f3d749bb18a5aafbeb2fe45ff5ebc8900aba8445 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Thu, 21 Mar 2013 15:45:41 -0700 Subject: [PATCH 002/285] start using object literal syntax --- .../WebViewJavascriptBridge.m | 39 ++++++++----------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 7d42de4d..33f4c696 100755 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -69,7 +69,7 @@ - (void)callHandler:(NSString *)handlerName data:(id)data responseCallback:(WVJB } - (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler { - [self.messageHandlers setObject:handler forKey:handlerName]; + self.messageHandlers[handlerName] = handler; } - (void)reset { @@ -83,12 +83,12 @@ - (void)_sendData:(NSDictionary *)data responseCallback:(WVJBResponseCallback)re if (responseCallback) { NSString* callbackId = [NSString stringWithFormat:@"objc_cb_%d", ++_uniqueId]; - [self.responseCallbacks setObject:responseCallback forKey:callbackId]; - [message setObject:callbackId forKey:@"callbackId"]; + self.responseCallbacks[callbackId] = responseCallback; + message[@"callbackId"] = callbackId; } if (handlerName) { - [message setObject:handlerName forKey:@"handlerName"]; + message[@"handlerName"] = handlerName; } [self _queueMessage:message]; } @@ -127,20 +127,17 @@ - (void)_flushMessageQueue { NSDictionary* message = [self _deserializeMessageJSON:messageJSON]; - NSString* responseId = [message objectForKey:@"responseId"]; + NSString* responseId = message[@"responseId"]; if (responseId) { - WVJBResponseCallback responseCallback = [_responseCallbacks objectForKey:responseId]; - responseCallback([message objectForKey:@"responseData"]); + WVJBResponseCallback responseCallback = _responseCallbacks[responseId]; + responseCallback(message[@"responseData"]); [_responseCallbacks removeObjectForKey:responseId]; } else { WVJBResponseCallback responseCallback = NULL; - __block NSString* callbackId = [message objectForKey:@"callbackId"]; + __block NSString* callbackId = message[@"callbackId"]; if (callbackId) { - __block bool wasCalled = false; responseCallback = ^(id responseData) { - if (wasCalled) { return; } - wasCalled = true; - NSDictionary* message = [NSDictionary dictionaryWithObjectsAndKeys: callbackId, @"responseId", responseData, @"responseData", nil]; + NSDictionary* message = @{ @"responseId":callbackId, @"responseData":responseData }; [self _queueMessage:message]; }; } else { @@ -149,20 +146,16 @@ - (void)_flushMessageQueue { }; } - WVJBHandler handler = self.messageHandler; - - NSString* handlerName = [message objectForKey:@"handlerName"]; - if (handlerName) { - handler = [_messageHandlers objectForKey:handlerName]; - } - - if (!handler) { - NSLog(@"WVJB Warning: No handler for %@", handlerName); - return; + WVJBHandler handler; + if (message[@"handlerName"]) { + handler = _messageHandlers[message[@"handlerName"]]; + if (!handler) { return NSLog(@"WVJB Warning: No handler for %@", message[@"handlerName"]); } + } else { + handler = self.messageHandler; } @try { - NSDictionary* data = [message objectForKey:@"data"]; + NSDictionary* data = message[@"data"]; if (!data || ((id)data) == [NSNull null]) { data = [NSDictionary dictionary]; } handler(data, responseCallback); } From dc42e9cbf025da7d92448495e65e1928fb599012 Mon Sep 17 00:00:00 2001 From: Kelp Date: Thu, 4 Apr 2013 01:54:06 +0800 Subject: [PATCH 003/285] fixed build failed. --- ExampleApp.xcodeproj/project.pbxproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ExampleApp.xcodeproj/project.pbxproj b/ExampleApp.xcodeproj/project.pbxproj index fedc8efc..2a13d565 100644 --- a/ExampleApp.xcodeproj/project.pbxproj +++ b/ExampleApp.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 2CCA595D1612A12500C966A2 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2CCA595C1612A12500C966A2 /* Default-568h@2x.png */; }; 2CEB3EC01602563600548120 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EBF1602563600548120 /* UIKit.framework */; }; 2CEB3EC21602563600548120 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EC11602563600548120 /* Foundation.framework */; }; 2CEB3EC41602563600548120 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EC31602563600548120 /* CoreGraphics.framework */; }; @@ -20,7 +19,6 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 2CCA595C1612A12500C966A2 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 2CEB3EBB1602563600548120 /* ExampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 2CEB3EBF1602563600548120 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 2CEB3EC11602563600548120 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -54,7 +52,6 @@ 2CEB3EB01602563600548120 = { isa = PBXGroup; children = ( - 2CCA595C1612A12500C966A2 /* Default-568h@2x.png */, 2CEB3EC51602563600548120 /* ExampleApp */, 2CEB3EBE1602563600548120 /* Frameworks */, 2CEB3EBC1602563600548120 /* Products */, @@ -166,7 +163,6 @@ 2CEB3ECA1602563600548120 /* InfoPlist.strings in Resources */, 2CEB3F5216025A4E00548120 /* WebViewJavascriptBridge.js.txt in Resources */, 2CEB3F5516025A9000548120 /* ExampleApp.html in Resources */, - 2CCA595D1612A12500C966A2 /* Default-568h@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; From 3b57d6ca60f81084d874052f2af810ebcb54314e Mon Sep 17 00:00:00 2001 From: xzeror Date: Wed, 3 Apr 2013 23:41:08 +0400 Subject: [PATCH 004/285] Fixed crashes on callbacks from JS Blocks not copied when saved in lists inside bridge. That leads to crash on callback from JS because callback block doesn't exist at that moment. --- WebViewJavascriptBridge.podspec | 14 ++++++++++++++ WebViewJavascriptBridge/WebViewJavascriptBridge.m | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 WebViewJavascriptBridge.podspec diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec new file mode 100644 index 00000000..e4d53599 --- /dev/null +++ b/WebViewJavascriptBridge.podspec @@ -0,0 +1,14 @@ +Pod::Spec.new do |s| + s.name = "WebViewJavascriptBridge" + s.version = "2.1.1" + s.summary = "A standalone iOS class for sending messages to and from javascript in a UIWebView." + s.homepage = "http://github.com/marcuswestin/WebViewJavascriptBridge" + s.license = { :type => "MIT", :file => "LICENSE" } + s.author = { "marcuswestin" => "marcus.westin@gmail.com" } + s.source = { :git => "https://github.com/marcuswestin/WebViewJavascriptBridge.git", :tag => "2.1.1" } + s.platform = :ios, "4.2" + s.source_files = "WebViewJavascriptBridge/WebViewJavascriptBridge.{h,m}" + s.resource = "WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt" + s.framework = "UIKit" + s.dependency "JSONKit" +end diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 7d42de4d..b7a98682 100755 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -69,7 +69,7 @@ - (void)callHandler:(NSString *)handlerName data:(id)data responseCallback:(WVJB } - (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler { - [self.messageHandlers setObject:handler forKey:handlerName]; + [self.messageHandlers setObject:[handler copy] forKey:handlerName]; } - (void)reset { @@ -83,7 +83,7 @@ - (void)_sendData:(NSDictionary *)data responseCallback:(WVJBResponseCallback)re if (responseCallback) { NSString* callbackId = [NSString stringWithFormat:@"objc_cb_%d", ++_uniqueId]; - [self.responseCallbacks setObject:responseCallback forKey:callbackId]; + [self.responseCallbacks setObject:[responseCallback copy] forKey:callbackId]; [message setObject:callbackId forKey:@"callbackId"]; } From 0b8062b591e5d4f104eab4b2104942e3c0778c7c Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Thu, 4 Apr 2013 12:24:50 -0700 Subject: [PATCH 005/285] v2.1.2 --- Changelog | 3 +++ WebViewJavascriptBridge.podspec | 14 -------------- 2 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 WebViewJavascriptBridge.podspec diff --git a/Changelog b/Changelog index 93b001e5..7733b5ac 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,6 @@ +v2.1.2 ++ Copy handler and response blocks + v2.1.1 + Handle edge cases gracefully (e.g. don't crash on unknown command or unexpected response) diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec deleted file mode 100644 index e4d53599..00000000 --- a/WebViewJavascriptBridge.podspec +++ /dev/null @@ -1,14 +0,0 @@ -Pod::Spec.new do |s| - s.name = "WebViewJavascriptBridge" - s.version = "2.1.1" - s.summary = "A standalone iOS class for sending messages to and from javascript in a UIWebView." - s.homepage = "http://github.com/marcuswestin/WebViewJavascriptBridge" - s.license = { :type => "MIT", :file => "LICENSE" } - s.author = { "marcuswestin" => "marcus.westin@gmail.com" } - s.source = { :git => "https://github.com/marcuswestin/WebViewJavascriptBridge.git", :tag => "2.1.1" } - s.platform = :ios, "4.2" - s.source_files = "WebViewJavascriptBridge/WebViewJavascriptBridge.{h,m}" - s.resource = "WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt" - s.framework = "UIKit" - s.dependency "JSONKit" -end From 9365d61374186f98c0e6a0ae0c22baca16df4f50 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Thu, 4 Apr 2013 12:28:53 -0700 Subject: [PATCH 006/285] add iphone5 splash screen; add @szeror and @kelp404 to list of contributors --- Default-568h@2x.png | Bin 0 -> 18594 bytes ExampleApp.xcodeproj/project.pbxproj | 4 ++++ README.md | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 Default-568h@2x.png diff --git a/Default-568h@2x.png b/Default-568h@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0891b7aabfcf3422423b109c8beed2bab838c607 GIT binary patch literal 18594 zcmeI4X;f257Jx&9fS`ixvS;&$x8J@slQFSel)6zJN=?13FB7H(lQjRkSy8x_-S~tvu2gzn1oS+dLcF#eqtq$ z%tf9TTvX?`)R@}3uBI;jzS-=ZR-Td&MHaS&;!0?Ni*#$#`n*~CcQK)Q9vAQ~TUpnI!j)a2biYK^R)M~A5wUDZhx?ULMX z3x1P&qt=trOY6P2U67L=m=U?F|5#Uj(eCueNTZaHs_ceWiHeET+j+tp3Jt9g(ekqP z2WOvfR{qV+9r+o4J5?qK>7;;^+I7tGv-i)es$X_D=EoKF+S?zsyj^oRFElP}c}JT< zd8SUs-?O?}2YD#ngKbnHgzHBcboxK_2r9l(?eNCl-pEzkJm}fY?WC*jnS?VBE4EpY zO$fEejz6fU;W2Kl>JeQBZBl-%Irg`obSlg*@4QB;Dd1H7^Oi5wvt4d{RZ!8Og?^aE z)k0$1g+V3fd(gdQ3d&q2q-FL*uy#}|bc^=VhFsl0jBgUGJ+-s3U8MK9A!YJJMxpci z5hJ%|{DwV48fZn0{n5l$N_KcSb#NKE4plB`9I6Zt=Z!~-zw0{9tg$L&Ju1F0X)Cy8 zKF;(&lJ>x)Jw(=;p~sF(Sd9VWGwFE2rnyS9!f^DZ8+aCLq zQ};>lcJ1GDLqjm6Hd>|Eabno@P`~Bn(~6^aD_#yoEH(a?Nm1S<;S+hSxI5d16^<1lEM3NPFi zkqPrpL)+ zgnseFikg`gJVBha1&7C4;O6>h=dt~`ND+;Zd?W(4v2JIb7Pt>Td42%M-Ju-XAH#Pns762L}K3 zDhvsRqN0Ni(1UrishD2YvV?4*h2iFj$+&N||Fn$4n|^NSU+o?~jq`0jVQt8T9l{7b zXiwwODFh2V!Q6sqP9S>WH$oOf$N~=d0-bqTlD61!=`&0eAP-F>XN?*|gtOXX{ zQVTWyYo4ZK0GAw!GHf|pz9`D;-bbb*5LBX*{bnz|+)$@&P9|ORM2o?95{;ejvo&r- zq8cBhTN6nn)7~W>54U)%-F_-b?YKdfk5I8MHcuzBD5)!;yv#Z&R&^y=@=>VTIMy#r zX&U<=BsPkdqcMe<_}2+>H%XKyrr5ZR8_KVe>ZqYN z^=^~TFD};;rHJ$U;{~w^hYojl4hRI@SH$^K{YEo=sg)WY87r!*7blQK&qnpDo0`Vn zkl)9u9g=mCh&ZCJS(L4yN3k0kQ zuvg$h2KEEk51T+O0JQ+r0`R>g{jvqM0Mr6d3qUOZwE!?PI7HY@CE|dr sfw?Q;rAv?G4&^^8-z_>&sWXMxvD*gPOU4CBe-*@OtE+wfmVJNyHv)PfH~;_u literal 0 HcmV?d00001 diff --git a/ExampleApp.xcodeproj/project.pbxproj b/ExampleApp.xcodeproj/project.pbxproj index 2a13d565..824f7fdf 100644 --- a/ExampleApp.xcodeproj/project.pbxproj +++ b/ExampleApp.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 2CEB3F5216025A4E00548120 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CEB3F5016025A4E00548120 /* WebViewJavascriptBridge.js.txt */; }; 2CEB3F5316025A4E00548120 /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CEB3F5116025A4E00548120 /* WebViewJavascriptBridge.m */; }; 2CEB3F5516025A9000548120 /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CEB3F5416025A9000548120 /* ExampleApp.html */; }; + 2CF988CE170E0BA500CA0CC7 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2CF988CD170E0BA500CA0CC7 /* Default-568h@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -33,6 +34,7 @@ 2CEB3F5016025A4E00548120 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; lineEnding = 0; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; 2CEB3F5116025A4E00548120 /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = WebViewJavascriptBridge.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 2CEB3F5416025A9000548120 /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = ""; }; + 2CF988CD170E0BA500CA0CC7 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -52,6 +54,7 @@ 2CEB3EB01602563600548120 = { isa = PBXGroup; children = ( + 2CF988CD170E0BA500CA0CC7 /* Default-568h@2x.png */, 2CEB3EC51602563600548120 /* ExampleApp */, 2CEB3EBE1602563600548120 /* Frameworks */, 2CEB3EBC1602563600548120 /* Products */, @@ -163,6 +166,7 @@ 2CEB3ECA1602563600548120 /* InfoPlist.strings in Resources */, 2CEB3F5216025A4E00548120 /* WebViewJavascriptBridge.js.txt in Resources */, 2CEB3F5516025A9000548120 /* ExampleApp.html in Resources */, + 2CF988CE170E0BA500CA0CC7 /* Default-568h@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/README.md b/README.md index f4b5c693..b1ead06e 100644 --- a/README.md +++ b/README.md @@ -197,4 +197,6 @@ Contributors - [@stringbean](https://github.com/stringbean) Michael Stringer - [@tanis2000](https://github.com/tanis2000) Valerio Santinelli - [@drewburch](https://github.com/drewburch) Andrew Burch -- [@pj4533](https://github.com/pj4533) PJ Gray \ No newline at end of file +- [@pj4533](https://github.com/pj4533) PJ Gray +- [@xzeror](https://github.com/xzeror) +- [@kelp404](https://github.com/kelp404) From a22f5e19987511913bbb9d605e7c470893e365f3 Mon Sep 17 00:00:00 2001 From: Antoine Lagadec Date: Sun, 7 Apr 2013 11:39:53 +0200 Subject: [PATCH 007/285] Rename ExampleApp into Example-iOS --- .../project.pbxproj | 142 +++++++++--------- .../ExampleApp-iOS-Info.plist | 0 .../ExampleApp-iOS-Prefix.pch | 0 .../ExampleApp.html | 0 .../ExampleAppDelegate.h | 0 .../ExampleAppDelegate.m | 0 .../en.lproj/InfoPlist.strings | 0 {ExampleApp => ExampleApp-iOS}/main.m | 0 8 files changed, 68 insertions(+), 74 deletions(-) rename {ExampleApp.xcodeproj => ExampleApp-iOS.xcodeproj}/project.pbxproj (63%) rename ExampleApp/ExampleApp-Info.plist => ExampleApp-iOS/ExampleApp-iOS-Info.plist (100%) rename ExampleApp/ExampleApp-Prefix.pch => ExampleApp-iOS/ExampleApp-iOS-Prefix.pch (100%) rename {ExampleApp => ExampleApp-iOS}/ExampleApp.html (100%) rename {ExampleApp => ExampleApp-iOS}/ExampleAppDelegate.h (100%) rename {ExampleApp => ExampleApp-iOS}/ExampleAppDelegate.m (100%) rename {ExampleApp => ExampleApp-iOS}/en.lproj/InfoPlist.strings (100%) rename {ExampleApp => ExampleApp-iOS}/main.m (100%) diff --git a/ExampleApp.xcodeproj/project.pbxproj b/ExampleApp-iOS.xcodeproj/project.pbxproj similarity index 63% rename from ExampleApp.xcodeproj/project.pbxproj rename to ExampleApp-iOS.xcodeproj/project.pbxproj index 824f7fdf..19311db7 100644 --- a/ExampleApp.xcodeproj/project.pbxproj +++ b/ExampleApp-iOS.xcodeproj/project.pbxproj @@ -7,33 +7,34 @@ objects = { /* Begin PBXBuildFile section */ + 2CA045BF17117439006DEE8B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045B717117439006DEE8B /* InfoPlist.strings */; }; + 2CA045C017117439006DEE8B /* ExampleApp-iOS-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045B917117439006DEE8B /* ExampleApp-iOS-Info.plist */; }; + 2CA045C117117439006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045BB17117439006DEE8B /* ExampleApp.html */; }; + 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */; }; + 2CA045C317117439006DEE8B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BE17117439006DEE8B /* main.m */; }; + 2CA045C81711745D006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045C61711745D006DEE8B /* WebViewJavascriptBridge.js.txt */; }; + 2CA045C91711745D006DEE8B /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045C71711745D006DEE8B /* WebViewJavascriptBridge.m */; }; 2CEB3EC01602563600548120 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EBF1602563600548120 /* UIKit.framework */; }; 2CEB3EC21602563600548120 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EC11602563600548120 /* Foundation.framework */; }; 2CEB3EC41602563600548120 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EC31602563600548120 /* CoreGraphics.framework */; }; - 2CEB3ECA1602563600548120 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2CEB3EC81602563600548120 /* InfoPlist.strings */; }; - 2CEB3ECC1602563600548120 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CEB3ECB1602563600548120 /* main.m */; }; - 2CEB3ED01602563600548120 /* ExampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CEB3ECF1602563600548120 /* ExampleAppDelegate.m */; }; - 2CEB3F5216025A4E00548120 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CEB3F5016025A4E00548120 /* WebViewJavascriptBridge.js.txt */; }; - 2CEB3F5316025A4E00548120 /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CEB3F5116025A4E00548120 /* WebViewJavascriptBridge.m */; }; - 2CEB3F5516025A9000548120 /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CEB3F5416025A9000548120 /* ExampleApp.html */; }; 2CF988CE170E0BA500CA0CC7 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2CF988CD170E0BA500CA0CC7 /* Default-568h@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 2CEB3EBB1602563600548120 /* ExampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 2CA045B817117439006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 2CA045B917117439006DEE8B /* ExampleApp-iOS-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ExampleApp-iOS-Info.plist"; sourceTree = ""; }; + 2CA045BA17117439006DEE8B /* ExampleApp-iOS-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ExampleApp-iOS-Prefix.pch"; sourceTree = ""; }; + 2CA045BB17117439006DEE8B /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = ""; }; + 2CA045BC17117439006DEE8B /* ExampleAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExampleAppDelegate.h; sourceTree = ""; }; + 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleAppDelegate.m; sourceTree = ""; }; + 2CA045BE17117439006DEE8B /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2CA045C51711745D006DEE8B /* WebViewJavascriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge.h; sourceTree = ""; }; + 2CA045C61711745D006DEE8B /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; + 2CA045C71711745D006DEE8B /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge.m; sourceTree = ""; }; + 2CEB3EBB1602563600548120 /* ExampleApp-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ExampleApp-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 2CEB3EBF1602563600548120 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 2CEB3EC11602563600548120 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 2CEB3EC31602563600548120 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - 2CEB3EC71602563600548120 /* ExampleApp-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ExampleApp-Info.plist"; sourceTree = ""; }; - 2CEB3EC91602563600548120 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - 2CEB3ECB1602563600548120 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 2CEB3ECD1602563600548120 /* ExampleApp-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ExampleApp-Prefix.pch"; sourceTree = ""; }; - 2CEB3ECE1602563600548120 /* ExampleAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExampleAppDelegate.h; sourceTree = ""; }; - 2CEB3ECF1602563600548120 /* ExampleAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleAppDelegate.m; sourceTree = ""; }; - 2CEB3F4F16025A4E00548120 /* WebViewJavascriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = WebViewJavascriptBridge.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - 2CEB3F5016025A4E00548120 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; lineEnding = 0; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; - 2CEB3F5116025A4E00548120 /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = WebViewJavascriptBridge.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 2CEB3F5416025A9000548120 /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = ""; }; 2CF988CD170E0BA500CA0CC7 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -51,11 +52,36 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 2CA045B617117439006DEE8B /* ExampleApp-iOS */ = { + isa = PBXGroup; + children = ( + 2CA045C41711745D006DEE8B /* WebViewJavascriptBridge */, + 2CA045B717117439006DEE8B /* InfoPlist.strings */, + 2CA045B917117439006DEE8B /* ExampleApp-iOS-Info.plist */, + 2CA045BA17117439006DEE8B /* ExampleApp-iOS-Prefix.pch */, + 2CA045BB17117439006DEE8B /* ExampleApp.html */, + 2CA045BC17117439006DEE8B /* ExampleAppDelegate.h */, + 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */, + 2CA045BE17117439006DEE8B /* main.m */, + ); + path = "ExampleApp-iOS"; + sourceTree = ""; + }; + 2CA045C41711745D006DEE8B /* WebViewJavascriptBridge */ = { + isa = PBXGroup; + children = ( + 2CA045C51711745D006DEE8B /* WebViewJavascriptBridge.h */, + 2CA045C61711745D006DEE8B /* WebViewJavascriptBridge.js.txt */, + 2CA045C71711745D006DEE8B /* WebViewJavascriptBridge.m */, + ); + path = WebViewJavascriptBridge; + sourceTree = SOURCE_ROOT; + }; 2CEB3EB01602563600548120 = { isa = PBXGroup; children = ( 2CF988CD170E0BA500CA0CC7 /* Default-568h@2x.png */, - 2CEB3EC51602563600548120 /* ExampleApp */, + 2CA045B617117439006DEE8B /* ExampleApp-iOS */, 2CEB3EBE1602563600548120 /* Frameworks */, 2CEB3EBC1602563600548120 /* Products */, ); @@ -64,7 +90,7 @@ 2CEB3EBC1602563600548120 /* Products */ = { isa = PBXGroup; children = ( - 2CEB3EBB1602563600548120 /* ExampleApp.app */, + 2CEB3EBB1602563600548120 /* ExampleApp-iOS.app */, ); name = Products; sourceTree = ""; @@ -79,45 +105,12 @@ name = Frameworks; sourceTree = ""; }; - 2CEB3EC51602563600548120 /* ExampleApp */ = { - isa = PBXGroup; - children = ( - 2CEB3ECE1602563600548120 /* ExampleAppDelegate.h */, - 2CEB3ECF1602563600548120 /* ExampleAppDelegate.m */, - 2CEB3F5416025A9000548120 /* ExampleApp.html */, - 2CEB3F4E16025A4E00548120 /* WebViewJavascriptBridge */, - 2CEB3EC61602563600548120 /* Supporting Files */, - ); - path = ExampleApp; - sourceTree = ""; - }; - 2CEB3EC61602563600548120 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 2CEB3EC71602563600548120 /* ExampleApp-Info.plist */, - 2CEB3EC81602563600548120 /* InfoPlist.strings */, - 2CEB3ECB1602563600548120 /* main.m */, - 2CEB3ECD1602563600548120 /* ExampleApp-Prefix.pch */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 2CEB3F4E16025A4E00548120 /* WebViewJavascriptBridge */ = { - isa = PBXGroup; - children = ( - 2CEB3F4F16025A4E00548120 /* WebViewJavascriptBridge.h */, - 2CEB3F5016025A4E00548120 /* WebViewJavascriptBridge.js.txt */, - 2CEB3F5116025A4E00548120 /* WebViewJavascriptBridge.m */, - ); - path = WebViewJavascriptBridge; - sourceTree = SOURCE_ROOT; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 2CEB3EBA1602563600548120 /* ExampleApp */ = { + 2CEB3EBA1602563600548120 /* ExampleApp-iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 2CEB3ED31602563600548120 /* Build configuration list for PBXNativeTarget "ExampleApp" */; + buildConfigurationList = 2CEB3ED31602563600548120 /* Build configuration list for PBXNativeTarget "ExampleApp-iOS" */; buildPhases = ( 2CEB3EB71602563600548120 /* Sources */, 2CEB3EB81602563600548120 /* Frameworks */, @@ -127,9 +120,9 @@ ); dependencies = ( ); - name = ExampleApp; + name = "ExampleApp-iOS"; productName = ExampleApp; - productReference = 2CEB3EBB1602563600548120 /* ExampleApp.app */; + productReference = 2CEB3EBB1602563600548120 /* ExampleApp-iOS.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -141,7 +134,7 @@ LastUpgradeCheck = 0450; ORGANIZATIONNAME = "Marcus Westin"; }; - buildConfigurationList = 2CEB3EB51602563600548120 /* Build configuration list for PBXProject "ExampleApp" */; + buildConfigurationList = 2CEB3EB51602563600548120 /* Build configuration list for PBXProject "ExampleApp-iOS" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; @@ -153,7 +146,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 2CEB3EBA1602563600548120 /* ExampleApp */, + 2CEB3EBA1602563600548120 /* ExampleApp-iOS */, ); }; /* End PBXProject section */ @@ -163,10 +156,11 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2CEB3ECA1602563600548120 /* InfoPlist.strings in Resources */, - 2CEB3F5216025A4E00548120 /* WebViewJavascriptBridge.js.txt in Resources */, - 2CEB3F5516025A9000548120 /* ExampleApp.html in Resources */, 2CF988CE170E0BA500CA0CC7 /* Default-568h@2x.png in Resources */, + 2CA045BF17117439006DEE8B /* InfoPlist.strings in Resources */, + 2CA045C017117439006DEE8B /* ExampleApp-iOS-Info.plist in Resources */, + 2CA045C117117439006DEE8B /* ExampleApp.html in Resources */, + 2CA045C81711745D006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -177,19 +171,19 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2CEB3ECC1602563600548120 /* main.m in Sources */, - 2CEB3ED01602563600548120 /* ExampleAppDelegate.m in Sources */, - 2CEB3F5316025A4E00548120 /* WebViewJavascriptBridge.m in Sources */, + 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */, + 2CA045C317117439006DEE8B /* main.m in Sources */, + 2CA045C91711745D006DEE8B /* WebViewJavascriptBridge.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ - 2CEB3EC81602563600548120 /* InfoPlist.strings */ = { + 2CA045B717117439006DEE8B /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( - 2CEB3EC91602563600548120 /* en */, + 2CA045B817117439006DEE8B /* en */, ); name = InfoPlist.strings; sourceTree = ""; @@ -248,9 +242,9 @@ isa = XCBuildConfiguration; buildSettings = { GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "ExampleApp/ExampleApp-Prefix.pch"; - INFOPLIST_FILE = "ExampleApp/ExampleApp-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; + GCC_PREFIX_HEADER = "ExampleApp-iOS/ExampleApp-iOS-Prefix.pch"; + INFOPLIST_FILE = "ExampleApp-iOS/ExampleApp-iOS-Info.plist"; + PRODUCT_NAME = "ExampleApp-iOS"; WRAPPER_EXTENSION = app; }; name = Debug; @@ -259,9 +253,9 @@ isa = XCBuildConfiguration; buildSettings = { GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "ExampleApp/ExampleApp-Prefix.pch"; - INFOPLIST_FILE = "ExampleApp/ExampleApp-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; + GCC_PREFIX_HEADER = "ExampleApp-iOS/ExampleApp-iOS-Prefix.pch"; + INFOPLIST_FILE = "ExampleApp-iOS/ExampleApp-iOS-Info.plist"; + PRODUCT_NAME = "ExampleApp-iOS"; WRAPPER_EXTENSION = app; }; name = Release; @@ -269,7 +263,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 2CEB3EB51602563600548120 /* Build configuration list for PBXProject "ExampleApp" */ = { + 2CEB3EB51602563600548120 /* Build configuration list for PBXProject "ExampleApp-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 2CEB3ED11602563600548120 /* Debug */, @@ -278,7 +272,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2CEB3ED31602563600548120 /* Build configuration list for PBXNativeTarget "ExampleApp" */ = { + 2CEB3ED31602563600548120 /* Build configuration list for PBXNativeTarget "ExampleApp-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 2CEB3ED41602563600548120 /* Debug */, diff --git a/ExampleApp/ExampleApp-Info.plist b/ExampleApp-iOS/ExampleApp-iOS-Info.plist similarity index 100% rename from ExampleApp/ExampleApp-Info.plist rename to ExampleApp-iOS/ExampleApp-iOS-Info.plist diff --git a/ExampleApp/ExampleApp-Prefix.pch b/ExampleApp-iOS/ExampleApp-iOS-Prefix.pch similarity index 100% rename from ExampleApp/ExampleApp-Prefix.pch rename to ExampleApp-iOS/ExampleApp-iOS-Prefix.pch diff --git a/ExampleApp/ExampleApp.html b/ExampleApp-iOS/ExampleApp.html similarity index 100% rename from ExampleApp/ExampleApp.html rename to ExampleApp-iOS/ExampleApp.html diff --git a/ExampleApp/ExampleAppDelegate.h b/ExampleApp-iOS/ExampleAppDelegate.h similarity index 100% rename from ExampleApp/ExampleAppDelegate.h rename to ExampleApp-iOS/ExampleAppDelegate.h diff --git a/ExampleApp/ExampleAppDelegate.m b/ExampleApp-iOS/ExampleAppDelegate.m similarity index 100% rename from ExampleApp/ExampleAppDelegate.m rename to ExampleApp-iOS/ExampleAppDelegate.m diff --git a/ExampleApp/en.lproj/InfoPlist.strings b/ExampleApp-iOS/en.lproj/InfoPlist.strings similarity index 100% rename from ExampleApp/en.lproj/InfoPlist.strings rename to ExampleApp-iOS/en.lproj/InfoPlist.strings diff --git a/ExampleApp/main.m b/ExampleApp-iOS/main.m similarity index 100% rename from ExampleApp/main.m rename to ExampleApp-iOS/main.m From 3943943bac99e0121300c627b19edc0445de0c34 Mon Sep 17 00:00:00 2001 From: Antoine Lagadec Date: Sun, 7 Apr 2013 14:57:27 +0200 Subject: [PATCH 008/285] Rework design so that we can provide an OSX version --- ExampleApp-iOS.xcodeproj/project.pbxproj | 20 +- ExampleApp-iOS/ExampleAppDelegate.h | 2 +- .../WebViewJavascriptBridge.h | 17 -- .../WebViewJavascriptBridge.m | 248 ------------------ .../WebViewJavascriptBridgeAbstract.h | 39 +++ .../WebViewJavascriptBridgeAbstract.m | 169 ++++++++++++ .../WebViewJavascriptBridge_iOS.h | 20 ++ .../WebViewJavascriptBridge_iOS.m | 84 ++++++ 8 files changed, 325 insertions(+), 274 deletions(-) delete mode 100644 WebViewJavascriptBridge/WebViewJavascriptBridge.h delete mode 100755 WebViewJavascriptBridge/WebViewJavascriptBridge.m create mode 100644 WebViewJavascriptBridge/WebViewJavascriptBridgeAbstract.h create mode 100755 WebViewJavascriptBridge/WebViewJavascriptBridgeAbstract.m create mode 100644 WebViewJavascriptBridge/WebViewJavascriptBridge_iOS.h create mode 100644 WebViewJavascriptBridge/WebViewJavascriptBridge_iOS.m diff --git a/ExampleApp-iOS.xcodeproj/project.pbxproj b/ExampleApp-iOS.xcodeproj/project.pbxproj index 19311db7..455727cb 100644 --- a/ExampleApp-iOS.xcodeproj/project.pbxproj +++ b/ExampleApp-iOS.xcodeproj/project.pbxproj @@ -8,12 +8,12 @@ /* Begin PBXBuildFile section */ 2CA045BF17117439006DEE8B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045B717117439006DEE8B /* InfoPlist.strings */; }; - 2CA045C017117439006DEE8B /* ExampleApp-iOS-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045B917117439006DEE8B /* ExampleApp-iOS-Info.plist */; }; 2CA045C117117439006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045BB17117439006DEE8B /* ExampleApp.html */; }; 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */; }; 2CA045C317117439006DEE8B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BE17117439006DEE8B /* main.m */; }; 2CA045C81711745D006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045C61711745D006DEE8B /* WebViewJavascriptBridge.js.txt */; }; - 2CA045C91711745D006DEE8B /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045C71711745D006DEE8B /* WebViewJavascriptBridge.m */; }; + 2CA045C91711745D006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045C71711745D006DEE8B /* WebViewJavascriptBridgeAbstract.m */; }; + 2CA0460817117BF9006DEE8B /* WebViewJavascriptBridge_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA0460717117BF9006DEE8B /* WebViewJavascriptBridge_iOS.m */; }; 2CEB3EC01602563600548120 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EBF1602563600548120 /* UIKit.framework */; }; 2CEB3EC21602563600548120 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EC11602563600548120 /* Foundation.framework */; }; 2CEB3EC41602563600548120 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EC31602563600548120 /* CoreGraphics.framework */; }; @@ -28,9 +28,11 @@ 2CA045BC17117439006DEE8B /* ExampleAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExampleAppDelegate.h; sourceTree = ""; }; 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleAppDelegate.m; sourceTree = ""; }; 2CA045BE17117439006DEE8B /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 2CA045C51711745D006DEE8B /* WebViewJavascriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge.h; sourceTree = ""; }; + 2CA045C51711745D006DEE8B /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; 2CA045C61711745D006DEE8B /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; - 2CA045C71711745D006DEE8B /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge.m; sourceTree = ""; }; + 2CA045C71711745D006DEE8B /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; + 2CA0460617117BF9006DEE8B /* WebViewJavascriptBridge_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_iOS.h; sourceTree = ""; }; + 2CA0460717117BF9006DEE8B /* WebViewJavascriptBridge_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_iOS.m; sourceTree = ""; }; 2CEB3EBB1602563600548120 /* ExampleApp-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ExampleApp-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 2CEB3EBF1602563600548120 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 2CEB3EC11602563600548120 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -70,9 +72,11 @@ 2CA045C41711745D006DEE8B /* WebViewJavascriptBridge */ = { isa = PBXGroup; children = ( - 2CA045C51711745D006DEE8B /* WebViewJavascriptBridge.h */, + 2CA045C51711745D006DEE8B /* WebViewJavascriptBridgeAbstract.h */, 2CA045C61711745D006DEE8B /* WebViewJavascriptBridge.js.txt */, - 2CA045C71711745D006DEE8B /* WebViewJavascriptBridge.m */, + 2CA045C71711745D006DEE8B /* WebViewJavascriptBridgeAbstract.m */, + 2CA0460617117BF9006DEE8B /* WebViewJavascriptBridge_iOS.h */, + 2CA0460717117BF9006DEE8B /* WebViewJavascriptBridge_iOS.m */, ); path = WebViewJavascriptBridge; sourceTree = SOURCE_ROOT; @@ -158,7 +162,6 @@ files = ( 2CF988CE170E0BA500CA0CC7 /* Default-568h@2x.png in Resources */, 2CA045BF17117439006DEE8B /* InfoPlist.strings in Resources */, - 2CA045C017117439006DEE8B /* ExampleApp-iOS-Info.plist in Resources */, 2CA045C117117439006DEE8B /* ExampleApp.html in Resources */, 2CA045C81711745D006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */, ); @@ -173,7 +176,8 @@ files = ( 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */, 2CA045C317117439006DEE8B /* main.m in Sources */, - 2CA045C91711745D006DEE8B /* WebViewJavascriptBridge.m in Sources */, + 2CA045C91711745D006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */, + 2CA0460817117BF9006DEE8B /* WebViewJavascriptBridge_iOS.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ExampleApp-iOS/ExampleAppDelegate.h b/ExampleApp-iOS/ExampleAppDelegate.h index 5fc2d78b..b85422c5 100644 --- a/ExampleApp-iOS/ExampleAppDelegate.h +++ b/ExampleApp-iOS/ExampleAppDelegate.h @@ -1,5 +1,5 @@ #import -#import "WebViewJavascriptBridge.h" +#import "WebViewJavascriptBridge_iOS.h" @interface ExampleAppDelegate : UIResponder diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.h b/WebViewJavascriptBridge/WebViewJavascriptBridge.h deleted file mode 100644 index 7eeaee3d..00000000 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.h +++ /dev/null @@ -1,17 +0,0 @@ -#import - -typedef void (^WVJBResponseCallback)(id responseData); -typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); - -@interface WebViewJavascriptBridge : NSObject -+ (id)bridgeForWebView:(UIWebView*)webView handler:(WVJBHandler)handler; -+ (id)bridgeForWebView:(UIWebView*)webView webViewDelegate:(id )webViewDelegate handler:(WVJBHandler)handler; -+ (void)enableLogging; -- (void)send:(id)message; -- (void)send:(id)message responseCallback:(WVJBResponseCallback)responseCallback; -- (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler; -- (void)callHandler:(NSString*)handlerName; -- (void)callHandler:(NSString*)handlerName data:(id)data; -- (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback; -- (void)reset; -@end diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m deleted file mode 100755 index bf5f9583..00000000 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ /dev/null @@ -1,248 +0,0 @@ -#import "WebViewJavascriptBridge.h" - -#ifdef USE_JSONKIT -#import "JSONKit.h" -#endif - -@interface WebViewJavascriptBridge () - -@property (nonatomic,strong) NSMutableArray *startupMessageQueue; -@property (nonatomic,strong) NSMutableDictionary *responseCallbacks; -@property (nonatomic,strong) NSMutableDictionary *messageHandlers; -@property (atomic,assign) NSInteger uniqueId; -@property (nonatomic, strong) UIWebView* webView; -@property (nonatomic, strong) id webViewDelegate; -@property (nonatomic, copy) WVJBHandler messageHandler; - -- (void)_flushMessageQueue; -- (void)_sendData:(NSDictionary*)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName; -- (void)_queueMessage:(NSDictionary*)message; -- (void)_dispatchMessage:(NSDictionary*)message; -- (NSString*)_serializeMessage:(NSDictionary*)message; -- (NSDictionary*)_deserializeMessageJSON:(NSString*)messageJSON; -- (void)_log:(NSString*)type json:(NSString*)output; - -@end - -@implementation WebViewJavascriptBridge - -static NSString *MESSAGE_SEPARATOR = @"__WVJB_MESSAGE_SEPERATOR__"; -static NSString *CUSTOM_PROTOCOL_SCHEME = @"wvjbscheme"; -static NSString *QUEUE_HAS_MESSAGE = @"__WVJB_QUEUE_MESSAGE__"; - -+ (id)bridgeForWebView:(UIWebView *)webView handler:(WVJBHandler)handler { - return [self bridgeForWebView:webView webViewDelegate:nil handler:handler]; -} - -+ (id)bridgeForWebView:(UIWebView *)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { - WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; - bridge.messageHandler = messageHandler; - bridge.webView = webView; - bridge.webViewDelegate = webViewDelegate; - bridge.messageHandlers = [NSMutableDictionary dictionary]; - [bridge reset]; - webView.delegate = bridge; - return bridge; -} - -static bool logging = false; -+ (void)enableLogging { logging = true; } - -- (void)send:(NSDictionary *)data { - [self send:data responseCallback:nil]; -} - -- (void)send:(NSDictionary *)data responseCallback:(WVJBResponseCallback)responseCallback { - [self _sendData:data responseCallback:responseCallback handlerName:nil]; -} - -- (void)callHandler:(NSString *)handlerName { - [self callHandler:handlerName data:nil responseCallback:nil]; -} - -- (void)callHandler:(NSString *)handlerName data:(id)data { - [self callHandler:handlerName data:data responseCallback:nil]; -} - -- (void)callHandler:(NSString *)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback { - [self _sendData:data responseCallback:responseCallback handlerName:handlerName]; -} - -- (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler { - self.messageHandlers[handlerName] = [handler copy]; -} - -- (void)reset { - self.startupMessageQueue = [NSMutableArray array]; - self.responseCallbacks = [NSMutableDictionary dictionary]; - self.uniqueId = 0; -} - -- (void)_sendData:(NSDictionary *)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName { - NSMutableDictionary* message = [NSMutableDictionary dictionaryWithObject:data forKey:@"data"]; - - if (responseCallback) { - NSString* callbackId = [NSString stringWithFormat:@"objc_cb_%d", ++_uniqueId]; - self.responseCallbacks[callbackId] = [responseCallback copy]; - message[@"callbackId"] = callbackId; - } - - if (handlerName) { - message[@"handlerName"] = handlerName; - } - [self _queueMessage:message]; -} - -- (void)_queueMessage:(NSDictionary *)message { - if (self.startupMessageQueue) { - [self.startupMessageQueue addObject:message]; - } else { - [self _dispatchMessage:message]; - } -} - -- (void)_dispatchMessage:(NSDictionary *)message { - NSString *messageJSON = [self _serializeMessage:message]; - [self _log:@"sending" json:messageJSON]; - messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; - messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; - messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\'" withString:@"\\\'"]; - messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]; - messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r" withString:@"\\r"]; - messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\f" withString:@"\\f"]; - if ([[NSThread currentThread] isMainThread]) { - [_webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]]; - } else { - dispatch_sync(dispatch_get_main_queue(), ^{ - [_webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]]; - }); - } -} - -- (void)_flushMessageQueue { - NSString *messageQueueString = [_webView stringByEvaluatingJavaScriptFromString:@"WebViewJavascriptBridge._fetchQueue();"]; - NSArray* messages = [messageQueueString componentsSeparatedByString:MESSAGE_SEPARATOR]; - for (NSString *messageJSON in messages) { - [self _log:@"receivd" json:messageJSON]; - - NSDictionary* message = [self _deserializeMessageJSON:messageJSON]; - - NSString* responseId = message[@"responseId"]; - if (responseId) { - WVJBResponseCallback responseCallback = _responseCallbacks[responseId]; - responseCallback(message[@"responseData"]); - [_responseCallbacks removeObjectForKey:responseId]; - } else { - WVJBResponseCallback responseCallback = NULL; - __block NSString* callbackId = message[@"callbackId"]; - if (callbackId) { - responseCallback = ^(id responseData) { - NSDictionary* message = @{ @"responseId":callbackId, @"responseData":responseData }; - [self _queueMessage:message]; - }; - } else { - responseCallback = ^(id ignoreResponseData) { - // Do nothing - }; - } - - WVJBHandler handler; - if (message[@"handlerName"]) { - handler = _messageHandlers[message[@"handlerName"]]; - if (!handler) { return NSLog(@"WVJB Warning: No handler for %@", message[@"handlerName"]); } - } else { - handler = self.messageHandler; - } - - @try { - NSDictionary* data = message[@"data"]; - if (!data || ((id)data) == [NSNull null]) { data = [NSDictionary dictionary]; } - handler(data, responseCallback); - } - @catch (NSException *exception) { - NSLog(@"WebViewJavascriptBridge: WARNING: objc handler threw. %@ %@", message, exception); - } - } - } -} - -- (NSString *)_serializeMessage:(NSDictionary *)message { - #ifdef USE_JSONKIT - return [message JSONString]; - #else - return [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:message options:0 error:nil] encoding:NSUTF8StringEncoding]; - #endif -} - -- (NSDictionary *)_deserializeMessageJSON:(NSString *)messageJSON { - #ifdef USE_JSONKIT - return [messageJSON objectFromJSONString]; - #else - return [NSJSONSerialization JSONObjectWithData:[messageJSON dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; - #endif -} - -- (void)_log:(NSString *)action json:(NSString *)json { - if (!logging) { return; } - if (json.length > 500) { - NSLog(@"WVJB %@: %@", action, [[json substringToIndex:500] stringByAppendingString:@" [...]"]); - } else { - NSLog(@"WVJB %@: %@", action, json); - } -} - -#pragma mark UIWebViewDelegate - -- (void)webViewDidFinishLoad:(UIWebView *)webView { - if (webView != _webView) { return; } - - if (![[_webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { - NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; - NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; - [_webView stringByEvaluatingJavaScriptFromString:js]; - } - - if (self.startupMessageQueue) { - for (id queuedMessage in self.startupMessageQueue) { - [self _dispatchMessage:queuedMessage]; - } - self.startupMessageQueue = nil; - } - - if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webViewDidFinishLoad:)]) { - [self.webViewDelegate webViewDidFinishLoad:webView]; - } -} - -- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { - if (webView != _webView) { return; } - if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) { - [self.webViewDelegate webView:_webView didFailLoadWithError:error]; - } -} - -- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { - if (webView != _webView) { return YES; } - NSURL *url = [request URL]; - if ([[url scheme] isEqualToString:CUSTOM_PROTOCOL_SCHEME]) { - if ([[url host] isEqualToString:QUEUE_HAS_MESSAGE]) { - [self _flushMessageQueue]; - } else { - NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", CUSTOM_PROTOCOL_SCHEME, [url path]); - } - return NO; - } else if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) { - return [self.webViewDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType]; - } else { - return YES; - } -} - -- (void)webViewDidStartLoad:(UIWebView *)webView { - if (webView != _webView) { return; } - if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webViewDidStartLoad:)]) { - [self.webViewDelegate webViewDidStartLoad:webView]; - } -} - -@end diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridgeAbstract.h b/WebViewJavascriptBridge/WebViewJavascriptBridgeAbstract.h new file mode 100644 index 00000000..11864b6a --- /dev/null +++ b/WebViewJavascriptBridge/WebViewJavascriptBridgeAbstract.h @@ -0,0 +1,39 @@ +#define kMessageSeparator @"__WVJB_MESSAGE_SEPERATOR__" +#define kCustomProtocolScheme @"wvjbscheme" +#define kQueueHasMessage @"__WVJB_QUEUE_MESSAGE__" + +typedef void (^WVJBResponseCallback)(id responseData); +typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); + +@interface WebViewJavascriptBridgeAbstract : NSObject + +@property (nonatomic, strong) id webView; +@property (nonatomic, strong) id webViewDelegate; +@property (nonatomic, strong) NSMutableArray *startupMessageQueue; +@property (nonatomic, strong) NSMutableDictionary *responseCallbacks; +@property (nonatomic, strong) NSMutableDictionary *messageHandlers; +@property (atomic, assign) NSInteger uniqueId; +@property (nonatomic, copy) WVJBHandler messageHandler; + ++ (void)enableLogging; +- (void)send:(id)message; +- (void)send:(id)message responseCallback:(WVJBResponseCallback)responseCallback; +- (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler; +- (void)callHandler:(NSString*)handlerName; +- (void)callHandler:(NSString*)handlerName data:(id)data; +- (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback; +- (void)reset; + +@end + +@interface WebViewJavascriptBridgeAbstract (Protected) + +- (void)_flushMessageQueue; +- (void)_sendData:(NSDictionary*)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName; +- (void)_queueMessage:(NSDictionary*)message; +- (void)_dispatchMessage:(NSDictionary*)message; +- (NSString*)_serializeMessage:(NSDictionary*)message; +- (NSDictionary*)_deserializeMessageJSON:(NSString*)messageJSON; +- (void)_log:(NSString*)type json:(NSString*)output; + +@end diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridgeAbstract.m b/WebViewJavascriptBridge/WebViewJavascriptBridgeAbstract.m new file mode 100755 index 00000000..830a5581 --- /dev/null +++ b/WebViewJavascriptBridge/WebViewJavascriptBridgeAbstract.m @@ -0,0 +1,169 @@ +#import "WebViewJavascriptBridgeAbstract.h" + +#ifdef USE_JSONKIT + #import "JSONKit.h" +#endif + +@interface WebViewJavascriptBridgeAbstract () + +@end + +@implementation WebViewJavascriptBridgeAbstract + +static bool logging = false; ++ (void)enableLogging { logging = true; } + +- (void)send:(NSDictionary *)data { + [self send:data responseCallback:nil]; +} + +- (void)send:(NSDictionary *)data responseCallback:(WVJBResponseCallback)responseCallback { + [self _sendData:data responseCallback:responseCallback handlerName:nil]; +} + +- (void)callHandler:(NSString *)handlerName { + [self callHandler:handlerName data:nil responseCallback:nil]; +} + +- (void)callHandler:(NSString *)handlerName data:(id)data { + [self callHandler:handlerName data:data responseCallback:nil]; +} + +- (void)callHandler:(NSString *)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback { + [self _sendData:data responseCallback:responseCallback handlerName:handlerName]; +} + +- (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler { + self.messageHandlers[handlerName] = [handler copy]; +} + +- (void)reset { + self.startupMessageQueue = [NSMutableArray array]; + self.responseCallbacks = [NSMutableDictionary dictionary]; + self.uniqueId = 0; +} + +@end + +@implementation WebViewJavascriptBridgeAbstract (Protected) + +- (void)_sendData:(NSDictionary *)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName { + NSMutableDictionary* message = [NSMutableDictionary dictionaryWithObject:data forKey:@"data"]; + + if (responseCallback) { + NSString* callbackId = [NSString stringWithFormat:@"objc_cb_%d", ++self.uniqueId]; + self.responseCallbacks[callbackId] = [responseCallback copy]; + message[@"callbackId"] = callbackId; + } + + if (handlerName) { + message[@"handlerName"] = handlerName; + } + [self _queueMessage:message]; +} + +- (void)_queueMessage:(NSDictionary *)message { + if (self.startupMessageQueue) { + [self.startupMessageQueue addObject:message]; + } else { + [self _dispatchMessage:message]; + } +} + +- (void)_dispatchMessage:(NSDictionary *)message { + NSString *messageJSON = [self _serializeMessage:message]; + [self _log:@"sending" json:messageJSON]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\'" withString:@"\\\'"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r" withString:@"\\r"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\f" withString:@"\\f"]; + if ([[NSThread currentThread] isMainThread]) { + [self.webView performSelector:@selector(stringByEvaluatingJavaScriptFromString:) + withObject:[NSString stringWithFormat: + @"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]]; + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ + [self.webView performSelector:@selector(stringByEvaluatingJavaScriptFromString:) + withObject:[NSString stringWithFormat: + @"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]]; + }); + } +} + +- (void)_flushMessageQueue { + NSString *messageQueueString = [self.webView performSelector: + @selector(stringByEvaluatingJavaScriptFromString:) withObject:@"WebViewJavascriptBridge._fetchQueue();"]; + + NSArray* messages = [messageQueueString componentsSeparatedByString:kMessageSeparator]; + for (NSString *messageJSON in messages) { + [self _log:@"receivd" json:messageJSON]; + + NSDictionary* message = [self _deserializeMessageJSON:messageJSON]; + + NSString* responseId = message[@"responseId"]; + if (responseId) { + WVJBResponseCallback responseCallback = self.responseCallbacks[responseId]; + responseCallback(message[@"responseData"]); + [self.responseCallbacks removeObjectForKey:responseId]; + } else { + WVJBResponseCallback responseCallback = NULL; + __block NSString* callbackId = message[@"callbackId"]; + if (callbackId) { + responseCallback = ^(id responseData) { + NSDictionary* message = @{ @"responseId":callbackId, @"responseData":responseData }; + [self _queueMessage:message]; + }; + } else { + responseCallback = ^(id ignoreResponseData) { + // Do nothing + }; + } + + WVJBHandler handler; + if (message[@"handlerName"]) { + handler = self.messageHandlers[message[@"handlerName"]]; + if (!handler) { return NSLog(@"WVJB Warning: No handler for %@", message[@"handlerName"]); } + } else { + handler = self.messageHandler; + } + + @try { + NSDictionary* data = message[@"data"]; + if (!data || ((id)data) == [NSNull null]) { data = [NSDictionary dictionary]; } + handler(data, responseCallback); + } + @catch (NSException *exception) { + NSLog(@"WebViewJavascriptBridge: WARNING: objc handler threw. %@ %@", message, exception); + } + } + } +} + +- (NSString *)_serializeMessage:(NSDictionary *)message { +#ifdef USE_JSONKIT + return [message JSONString]; +#else + return [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:message options:0 error:nil] encoding:NSUTF8StringEncoding]; +#endif +} + +- (NSDictionary *)_deserializeMessageJSON:(NSString *)messageJSON { +#ifdef USE_JSONKIT + return [messageJSON objectFromJSONString]; +#else + return [NSJSONSerialization JSONObjectWithData:[messageJSON dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; +#endif +} + +- (void)_log:(NSString *)action json:(NSString *)json { + if (!logging) { return; } + if (json.length > 500) { + NSLog(@"WVJB %@: %@", action, [[json substringToIndex:500] stringByAppendingString:@" [...]"]); + } else { + NSLog(@"WVJB %@: %@", action, json); + } +} + +@end diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge_iOS.h b/WebViewJavascriptBridge/WebViewJavascriptBridge_iOS.h new file mode 100644 index 00000000..3371f49f --- /dev/null +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge_iOS.h @@ -0,0 +1,20 @@ +// +// WebViewJavascriptBridge+iOS.h +// ExampleApp-iOS +// +// Created by Antoine Lagadec on 07/04/13. +// Copyright (c) 2013 Marcus Westin. All rights reserved. +// + +#import +#import "WebViewJavascriptBridgeAbstract.h" + +@interface WebViewJavascriptBridge : WebViewJavascriptBridgeAbstract + +@property (nonatomic, strong) UIWebView *webView; +@property (nonatomic, strong) id webViewDelegate; + ++ (id)bridgeForWebView:(UIWebView*)webView handler:(WVJBHandler)handler; ++ (id)bridgeForWebView:(UIWebView*)webView webViewDelegate:(id )webViewDelegate handler:(WVJBHandler)handler; + +@end diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge_iOS.m b/WebViewJavascriptBridge/WebViewJavascriptBridge_iOS.m new file mode 100644 index 00000000..de493c85 --- /dev/null +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge_iOS.m @@ -0,0 +1,84 @@ +// +// WebViewJavascriptBridge+iOS.m +// ExampleApp-iOS +// +// Created by Antoine Lagadec on 07/04/13. +// Copyright (c) 2013 Marcus Westin. All rights reserved. +// + +#import "WebViewJavascriptBridge_iOS.h" + +@implementation WebViewJavascriptBridge + +#pragma mark UIWebViewDelegate + ++ (id)bridgeForWebView:(UIWebView *)webView handler:(WVJBHandler)handler { + return [self bridgeForWebView:webView webViewDelegate:nil handler:handler]; +} + ++ (id)bridgeForWebView:(UIWebView *)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { + WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; + bridge.messageHandler = messageHandler; + bridge.webView = webView; + bridge.webViewDelegate = webViewDelegate; + bridge.messageHandlers = [NSMutableDictionary dictionary]; + [bridge reset]; + + [webView setDelegate:bridge]; + + return bridge; +} + +- (void)webViewDidFinishLoad:(UIWebView *)webView { + if (webView != self.webView) { return; } + + if (![[self.webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { + NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; + NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; + [self.webView stringByEvaluatingJavaScriptFromString:js]; + } + + if (self.startupMessageQueue) { + for (id queuedMessage in self.startupMessageQueue) { + [self _dispatchMessage:queuedMessage]; + } + self.startupMessageQueue = nil; + } + + if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webViewDidFinishLoad:)]) { + [self.webViewDelegate webViewDidFinishLoad:webView]; + } +} + +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { + if (webView != self.webView) { return; } + if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) { + [self.webViewDelegate webView:self.webView didFailLoadWithError:error]; + } +} + +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { + if (webView != self.webView) { return YES; } + NSURL *url = [request URL]; + if ([[url scheme] isEqualToString:kCustomProtocolScheme]) { + if ([[url host] isEqualToString:kQueueHasMessage]) { + [self _flushMessageQueue]; + } else { + NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", kCustomProtocolScheme, [url path]); + } + return NO; + } else if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) { + return [self.webViewDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType]; + } else { + return YES; + } +} + +- (void)webViewDidStartLoad:(UIWebView *)webView { + if (webView != self.webView) { return; } + if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webViewDidStartLoad:)]) { + [self.webViewDelegate webViewDidStartLoad:webView]; + } +} + +@end From 2c29b112cf73c4528d761bcc9d2a7c1dafc09602 Mon Sep 17 00:00:00 2001 From: Antoine Lagadec Date: Sun, 7 Apr 2013 14:58:04 +0200 Subject: [PATCH 009/285] Add an OSX version --- ExampleApp-OSX.xcodeproj/project.pbxproj | 337 ++ ExampleApp-OSX/AppDelegate.h | 22 + ExampleApp-OSX/AppDelegate.m | 59 + ExampleApp-OSX/ExampleApp-OSX-Info.plist | 34 + ExampleApp-OSX/ExampleApp-OSX-Prefix.pch | 7 + ExampleApp-OSX/ExampleApp.html | 66 + ExampleApp-OSX/en.lproj/Credits.rtf | 29 + ExampleApp-OSX/en.lproj/InfoPlist.strings | 2 + ExampleApp-OSX/en.lproj/MainMenu.xib | 3614 +++++++++++++++++ ExampleApp-OSX/main.m | 14 + .../WebViewJavascriptBridge_OSX.h | 20 + .../WebViewJavascriptBridge_OSX.m | 96 + 12 files changed, 4300 insertions(+) create mode 100644 ExampleApp-OSX.xcodeproj/project.pbxproj create mode 100644 ExampleApp-OSX/AppDelegate.h create mode 100644 ExampleApp-OSX/AppDelegate.m create mode 100644 ExampleApp-OSX/ExampleApp-OSX-Info.plist create mode 100644 ExampleApp-OSX/ExampleApp-OSX-Prefix.pch create mode 100644 ExampleApp-OSX/ExampleApp.html create mode 100644 ExampleApp-OSX/en.lproj/Credits.rtf create mode 100644 ExampleApp-OSX/en.lproj/InfoPlist.strings create mode 100644 ExampleApp-OSX/en.lproj/MainMenu.xib create mode 100644 ExampleApp-OSX/main.m create mode 100644 WebViewJavascriptBridge/WebViewJavascriptBridge_OSX.h create mode 100644 WebViewJavascriptBridge/WebViewJavascriptBridge_OSX.m diff --git a/ExampleApp-OSX.xcodeproj/project.pbxproj b/ExampleApp-OSX.xcodeproj/project.pbxproj new file mode 100644 index 00000000..94d32ce7 --- /dev/null +++ b/ExampleApp-OSX.xcodeproj/project.pbxproj @@ -0,0 +1,337 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 2CA045DA171178E5006DEE8B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CA045D9171178E5006DEE8B /* Cocoa.framework */; }; + 2CA045E4171178E6006DEE8B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045E2171178E6006DEE8B /* InfoPlist.strings */; }; + 2CA045E6171178E6006DEE8B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045E5171178E6006DEE8B /* main.m */; }; + 2CA045EA171178E6006DEE8B /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045E8171178E6006DEE8B /* Credits.rtf */; }; + 2CA045ED171178E6006DEE8B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045EC171178E6006DEE8B /* AppDelegate.m */; }; + 2CA045F0171178E6006DEE8B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045EE171178E6006DEE8B /* MainMenu.xib */; }; + 2CA045FE17117A69006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045FC17117A69006DEE8B /* WebViewJavascriptBridge.js.txt */; }; + 2CA0460317117A84006DEE8B /* WebViewJavascriptBridge_OSX.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA0460217117A84006DEE8B /* WebViewJavascriptBridge_OSX.m */; }; + 2CA0460517117B56006DEE8B /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CA0460417117B56006DEE8B /* WebKit.framework */; }; + 2CA0460A17118B08006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA0460917118B08006DEE8B /* ExampleApp.html */; }; + 2CA046161711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA046151711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 2CA045D5171178E5006DEE8B /* ExampleApp-OSX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ExampleApp-OSX.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2CA045D9171178E5006DEE8B /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + 2CA045DC171178E5006DEE8B /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + 2CA045DD171178E5006DEE8B /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + 2CA045DE171178E5006DEE8B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 2CA045E1171178E6006DEE8B /* ExampleApp-OSX-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ExampleApp-OSX-Info.plist"; sourceTree = ""; }; + 2CA045E3171178E6006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 2CA045E5171178E6006DEE8B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2CA045E7171178E6006DEE8B /* ExampleApp-OSX-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ExampleApp-OSX-Prefix.pch"; sourceTree = ""; }; + 2CA045E9171178E6006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; + 2CA045EB171178E6006DEE8B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 2CA045EC171178E6006DEE8B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 2CA045EF171178E6006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; + 2CA045FC17117A69006DEE8B /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; + 2CA0460117117A84006DEE8B /* WebViewJavascriptBridge_OSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_OSX.h; sourceTree = ""; }; + 2CA0460217117A84006DEE8B /* WebViewJavascriptBridge_OSX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_OSX.m; sourceTree = ""; }; + 2CA0460417117B56006DEE8B /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + 2CA0460917118B08006DEE8B /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = ""; }; + 2CA046141711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; + 2CA046151711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 2CA045D2171178E5006DEE8B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2CA0460517117B56006DEE8B /* WebKit.framework in Frameworks */, + 2CA045DA171178E5006DEE8B /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2CA045CA171178E5006DEE8B = { + isa = PBXGroup; + children = ( + 2CA0460417117B56006DEE8B /* WebKit.framework */, + 2CA045DF171178E5006DEE8B /* ExampleApp-OSX */, + 2CA045D8171178E5006DEE8B /* Frameworks */, + 2CA045D6171178E5006DEE8B /* Products */, + ); + sourceTree = ""; + }; + 2CA045D6171178E5006DEE8B /* Products */ = { + isa = PBXGroup; + children = ( + 2CA045D5171178E5006DEE8B /* ExampleApp-OSX.app */, + ); + name = Products; + sourceTree = ""; + }; + 2CA045D8171178E5006DEE8B /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2CA045D9171178E5006DEE8B /* Cocoa.framework */, + 2CA045DB171178E5006DEE8B /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2CA045DB171178E5006DEE8B /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 2CA045DC171178E5006DEE8B /* AppKit.framework */, + 2CA045DD171178E5006DEE8B /* CoreData.framework */, + 2CA045DE171178E5006DEE8B /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 2CA045DF171178E5006DEE8B /* ExampleApp-OSX */ = { + isa = PBXGroup; + children = ( + 2CA045EB171178E6006DEE8B /* AppDelegate.h */, + 2CA045EC171178E6006DEE8B /* AppDelegate.m */, + 2CA045EE171178E6006DEE8B /* MainMenu.xib */, + 2CA0460917118B08006DEE8B /* ExampleApp.html */, + 2CA045FA17117A69006DEE8B /* WebViewJavascriptBridge */, + 2CA045E0171178E6006DEE8B /* Supporting Files */, + ); + path = "ExampleApp-OSX"; + sourceTree = ""; + }; + 2CA045E0171178E6006DEE8B /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 2CA045E1171178E6006DEE8B /* ExampleApp-OSX-Info.plist */, + 2CA045E2171178E6006DEE8B /* InfoPlist.strings */, + 2CA045E5171178E6006DEE8B /* main.m */, + 2CA045E7171178E6006DEE8B /* ExampleApp-OSX-Prefix.pch */, + 2CA045E8171178E6006DEE8B /* Credits.rtf */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 2CA045FA17117A69006DEE8B /* WebViewJavascriptBridge */ = { + isa = PBXGroup; + children = ( + 2CA046141711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.h */, + 2CA046151711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.m */, + 2CA045FC17117A69006DEE8B /* WebViewJavascriptBridge.js.txt */, + 2CA0460117117A84006DEE8B /* WebViewJavascriptBridge_OSX.h */, + 2CA0460217117A84006DEE8B /* WebViewJavascriptBridge_OSX.m */, + ); + path = WebViewJavascriptBridge; + sourceTree = SOURCE_ROOT; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 2CA045D4171178E5006DEE8B /* ExampleApp-OSX */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2CA045F3171178E6006DEE8B /* Build configuration list for PBXNativeTarget "ExampleApp-OSX" */; + buildPhases = ( + 2CA045D1171178E5006DEE8B /* Sources */, + 2CA045D2171178E5006DEE8B /* Frameworks */, + 2CA045D3171178E5006DEE8B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "ExampleApp-OSX"; + productName = "ExampleApp-OSX"; + productReference = 2CA045D5171178E5006DEE8B /* ExampleApp-OSX.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 2CA045CC171178E5006DEE8B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0450; + ORGANIZATIONNAME = "Antoine Lagadec"; + }; + buildConfigurationList = 2CA045CF171178E5006DEE8B /* Build configuration list for PBXProject "ExampleApp-OSX" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 2CA045CA171178E5006DEE8B; + productRefGroup = 2CA045D6171178E5006DEE8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2CA045D4171178E5006DEE8B /* ExampleApp-OSX */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 2CA045D3171178E5006DEE8B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2CA045E4171178E6006DEE8B /* InfoPlist.strings in Resources */, + 2CA045EA171178E6006DEE8B /* Credits.rtf in Resources */, + 2CA045F0171178E6006DEE8B /* MainMenu.xib in Resources */, + 2CA045FE17117A69006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */, + 2CA0460A17118B08006DEE8B /* ExampleApp.html in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2CA045D1171178E5006DEE8B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2CA045E6171178E6006DEE8B /* main.m in Sources */, + 2CA045ED171178E6006DEE8B /* AppDelegate.m in Sources */, + 2CA0460317117A84006DEE8B /* WebViewJavascriptBridge_OSX.m in Sources */, + 2CA046161711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 2CA045E2171178E6006DEE8B /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 2CA045E3171178E6006DEE8B /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 2CA045E8171178E6006DEE8B /* Credits.rtf */ = { + isa = PBXVariantGroup; + children = ( + 2CA045E9171178E6006DEE8B /* en */, + ); + name = Credits.rtf; + sourceTree = ""; + }; + 2CA045EE171178E6006DEE8B /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 2CA045EF171178E6006DEE8B /* en */, + ); + name = MainMenu.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 2CA045F1171178E6006DEE8B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 2CA045F2171178E6006DEE8B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; + SDKROOT = macosx; + }; + name = Release; + }; + 2CA045F4171178E6006DEE8B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ExampleApp-OSX/ExampleApp-OSX-Prefix.pch"; + INFOPLIST_FILE = "ExampleApp-OSX/ExampleApp-OSX-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 2CA045F5171178E6006DEE8B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ExampleApp-OSX/ExampleApp-OSX-Prefix.pch"; + INFOPLIST_FILE = "ExampleApp-OSX/ExampleApp-OSX-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2CA045CF171178E5006DEE8B /* Build configuration list for PBXProject "ExampleApp-OSX" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2CA045F1171178E6006DEE8B /* Debug */, + 2CA045F2171178E6006DEE8B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2CA045F3171178E6006DEE8B /* Build configuration list for PBXNativeTarget "ExampleApp-OSX" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2CA045F4171178E6006DEE8B /* Debug */, + 2CA045F5171178E6006DEE8B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 2CA045CC171178E5006DEE8B /* Project object */; +} diff --git a/ExampleApp-OSX/AppDelegate.h b/ExampleApp-OSX/AppDelegate.h new file mode 100644 index 00000000..96bb190a --- /dev/null +++ b/ExampleApp-OSX/AppDelegate.h @@ -0,0 +1,22 @@ +// +// AppDelegate.h +// ExampleApp-OSX +// +// Created by Antoine Lagadec on 07/04/13. +// Copyright (c) 2013 Antoine Lagadec. All rights reserved. +// + +#import +#import "WebViewJavascriptBridge_OSX.h" + +@interface AppDelegate : NSObject + +@property (assign) IBOutlet NSWindow *window; +@property (weak) IBOutlet WebView *webView; + +- (IBAction)sendMessage:(id)sender; +- (IBAction)callHandler:(id)sender; + +@property (strong, nonatomic) WebViewJavascriptBridge *javascriptBridge; + +@end diff --git a/ExampleApp-OSX/AppDelegate.m b/ExampleApp-OSX/AppDelegate.m new file mode 100644 index 00000000..ed31863b --- /dev/null +++ b/ExampleApp-OSX/AppDelegate.m @@ -0,0 +1,59 @@ +// +// AppDelegate.m +// ExampleApp-OSX +// +// Created by Antoine Lagadec on 07/04/13. +// Copyright (c) 2013 Antoine Lagadec. All rights reserved. +// + +#import "AppDelegate.h" + +@implementation AppDelegate + +@synthesize javascriptBridge = _bridge; + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + [WebViewJavascriptBridge enableLogging]; + + _bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"ObjC received message from JS: %@", data); + responseCallback(@"Response for message from ObjC"); + }]; + + [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"testObjcCallback called: %@", data); + responseCallback(@"Response from testObjcCallback"); + }]; + + [_bridge send:@"A string sent from ObjC before Webview has loaded." responseCallback:^(id responseData) { + NSLog(@"objc got response! %@", responseData); + }]; + + [_bridge callHandler:@"testJavascriptHandler" data:[NSDictionary dictionaryWithObject:@"before ready" forKey:@"foo"]]; + + [self loadExamplePage:self.webView]; + + [_bridge send:@"A string sent from ObjC after Webview has loaded."]; +} + +- (IBAction)sendMessage:(id)sender { + [_bridge send:@"A string sent from ObjC to JS" responseCallback:^(id response) { + NSLog(@"sendMessage got response: %@", response); + }]; +} + +- (IBAction)callHandler:(id)sender { + NSDictionary* data = [NSDictionary dictionaryWithObject:@"Hi there, JS!" forKey:@"greetingFromObjC"]; + [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { + NSLog(@"testJavascriptHandler responded: %@", response); + }]; +} + +- (void)loadExamplePage:(WebView*)webView { + NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; + NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; + [[self.webView mainFrame] loadHTMLString:appHtml baseURL:nil]; +} + +@end diff --git a/ExampleApp-OSX/ExampleApp-OSX-Info.plist b/ExampleApp-OSX/ExampleApp-OSX-Info.plist new file mode 100644 index 00000000..5a46a8d8 --- /dev/null +++ b/ExampleApp-OSX/ExampleApp-OSX-Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + example.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + ${MACOSX_DEPLOYMENT_TARGET} + NSHumanReadableCopyright + Copyright © 2013 Antoine Lagadec. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch b/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch new file mode 100644 index 00000000..32daebd5 --- /dev/null +++ b/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'ExampleApp-OSX' target in the 'ExampleApp-OSX' project +// + +#ifdef __OBJC__ + #import +#endif diff --git a/ExampleApp-OSX/ExampleApp.html b/ExampleApp-OSX/ExampleApp.html new file mode 100644 index 00000000..30efb6c8 --- /dev/null +++ b/ExampleApp-OSX/ExampleApp.html @@ -0,0 +1,66 @@ + + + + +

WebViewJavascriptBridge Demo

+ +
+ diff --git a/ExampleApp-OSX/en.lproj/Credits.rtf b/ExampleApp-OSX/en.lproj/Credits.rtf new file mode 100644 index 00000000..46576ef2 --- /dev/null +++ b/ExampleApp-OSX/en.lproj/Credits.rtf @@ -0,0 +1,29 @@ +{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} +{\colortbl;\red255\green255\blue255;} +\paperw9840\paperh8400 +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\b\fs24 \cf0 Engineering: +\b0 \ + Some people\ +\ + +\b Human Interface Design: +\b0 \ + Some other people\ +\ + +\b Testing: +\b0 \ + Hopefully not nobody\ +\ + +\b Documentation: +\b0 \ + Whoever\ +\ + +\b With special thanks to: +\b0 \ + Mom\ +} diff --git a/ExampleApp-OSX/en.lproj/InfoPlist.strings b/ExampleApp-OSX/en.lproj/InfoPlist.strings new file mode 100644 index 00000000..477b28ff --- /dev/null +++ b/ExampleApp-OSX/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/ExampleApp-OSX/en.lproj/MainMenu.xib b/ExampleApp-OSX/en.lproj/MainMenu.xib new file mode 100644 index 00000000..b4989b1d --- /dev/null +++ b/ExampleApp-OSX/en.lproj/MainMenu.xib @@ -0,0 +1,3614 @@ + + + + 1070 + 11E53 + 2844 + 1138.47 + 569.00 + + 2844 + 1810 + + + IBNSLayoutConstraint + NSButton + NSButtonCell + NSCustomObject + NSMenu + NSMenuItem + NSView + NSWindowTemplate + WebView + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + + + PluginDependencyRecalculationVersion + + + + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + + + ExampleApp-OSX + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + ExampleApp-OSX + + + + About ExampleApp-OSX + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Preferences… + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + Services + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide ExampleApp-OSX + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit ExampleApp-OSX + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 1048576 + 2147483647 + + + submenuAction: + + File + + + + New + n + 1048576 + 2147483647 + + + + + + Open… + o + 1048576 + 2147483647 + + + + + + Open Recent + + 1048576 + 2147483647 + + + submenuAction: + + Open Recent + + + + Clear Menu + + 1048576 + 2147483647 + + + + + _NSRecentDocumentsMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Close + w + 1048576 + 2147483647 + + + + + + Save… + s + 1048576 + 2147483647 + + + + + + Revert to Saved + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Page Setup... + P + 1179648 + 2147483647 + + + + + + + Print… + p + 1048576 + 2147483647 + + + + + + + + + Edit + + 1048576 + 2147483647 + + + submenuAction: + + Edit + + + + Undo + z + 1048576 + 2147483647 + + + + + + Redo + Z + 1179648 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Cut + x + 1048576 + 2147483647 + + + + + + Copy + c + 1048576 + 2147483647 + + + + + + Paste + v + 1048576 + 2147483647 + + + + + + Paste and Match Style + V + 1572864 + 2147483647 + + + + + + Delete + + 1048576 + 2147483647 + + + + + + Select All + a + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Find + + 1048576 + 2147483647 + + + submenuAction: + + Find + + + + Find… + f + 1048576 + 2147483647 + + + 1 + + + + Find and Replace… + f + 1572864 + 2147483647 + + + 12 + + + + Find Next + g + 1048576 + 2147483647 + + + 2 + + + + Find Previous + G + 1179648 + 2147483647 + + + 3 + + + + Use Selection for Find + e + 1048576 + 2147483647 + + + 7 + + + + Jump to Selection + j + 1048576 + 2147483647 + + + + + + + + + Spelling and Grammar + + 1048576 + 2147483647 + + + submenuAction: + + Spelling and Grammar + + + + Show Spelling and Grammar + : + 1048576 + 2147483647 + + + + + + Check Document Now + ; + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Check Spelling While Typing + + 1048576 + 2147483647 + + + + + + Check Grammar With Spelling + + 1048576 + 2147483647 + + + + + + Correct Spelling Automatically + + 2147483647 + + + + + + + + + Substitutions + + 1048576 + 2147483647 + + + submenuAction: + + Substitutions + + + + Show Substitutions + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Smart Copy/Paste + f + 1048576 + 2147483647 + + + 1 + + + + Smart Quotes + g + 1048576 + 2147483647 + + + 2 + + + + Smart Dashes + + 2147483647 + + + + + + Smart Links + G + 1179648 + 2147483647 + + + 3 + + + + Text Replacement + + 2147483647 + + + + + + + + + Transformations + + 2147483647 + + + submenuAction: + + Transformations + + + + Make Upper Case + + 2147483647 + + + + + + Make Lower Case + + 2147483647 + + + + + + Capitalize + + 2147483647 + + + + + + + + + Speech + + 1048576 + 2147483647 + + + submenuAction: + + Speech + + + + Start Speaking + + 1048576 + 2147483647 + + + + + + Stop Speaking + + 1048576 + 2147483647 + + + + + + + + + + + + Format + + 2147483647 + + + submenuAction: + + Format + + + + Font + + 2147483647 + + + submenuAction: + + Font + + + + Show Fonts + t + 1048576 + 2147483647 + + + + + + Bold + b + 1048576 + 2147483647 + + + 2 + + + + Italic + i + 1048576 + 2147483647 + + + 1 + + + + Underline + u + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Bigger + + + 1048576 + 2147483647 + + + 3 + + + + Smaller + - + 1048576 + 2147483647 + + + 4 + + + + YES + YES + + + 2147483647 + + + + + + Kern + + 2147483647 + + + submenuAction: + + Kern + + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Tighten + + 2147483647 + + + + + + Loosen + + 2147483647 + + + + + + + + + Ligatures + + 2147483647 + + + submenuAction: + + Ligatures + + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Use All + + 2147483647 + + + + + + + + + Baseline + + 2147483647 + + + submenuAction: + + Baseline + + + + Use Default + + 2147483647 + + + + + + Superscript + + 2147483647 + + + + + + Subscript + + 2147483647 + + + + + + Raise + + 2147483647 + + + + + + Lower + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Colors + C + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Copy Style + c + 1572864 + 2147483647 + + + + + + Paste Style + v + 1572864 + 2147483647 + + + + + _NSFontMenu + + + + + Text + + 2147483647 + + + submenuAction: + + Text + + + + Align Left + { + 1048576 + 2147483647 + + + + + + Center + | + 1048576 + 2147483647 + + + + + + Justify + + 2147483647 + + + + + + Align Right + } + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Writing Direction + + 2147483647 + + + submenuAction: + + Writing Direction + + + + YES + Paragraph + + 2147483647 + + + + + + CURlZmF1bHQ + + 2147483647 + + + + + + CUxlZnQgdG8gUmlnaHQ + + 2147483647 + + + + + + CVJpZ2h0IHRvIExlZnQ + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + YES + Selection + + 2147483647 + + + + + + CURlZmF1bHQ + + 2147483647 + + + + + + CUxlZnQgdG8gUmlnaHQ + + 2147483647 + + + + + + CVJpZ2h0IHRvIExlZnQ + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Ruler + + 2147483647 + + + + + + Copy Ruler + c + 1310720 + 2147483647 + + + + + + Paste Ruler + v + 1310720 + 2147483647 + + + + + + + + + + + + View + + 1048576 + 2147483647 + + + submenuAction: + + View + + + + Show Toolbar + t + 1572864 + 2147483647 + + + + + + Customize Toolbar… + + 1048576 + 2147483647 + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + Window + + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 2147483647 + + + submenuAction: + + Help + + + + ExampleApp-OSX Help + ? + 1048576 + 2147483647 + + + + + _NSHelpMenu + + + + _NSMainMenu + + + 15 + 2 + {{335, 390}, {480, 360}} + 1954021376 + ExampleApp-OSX + NSWindow + + + + + 256 + + + + 256 + + Apple HTML pasteboard type + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple URL pasteboard type + Apple Web Archive pasteboard type + NSColor pasteboard type + NSFilenamesPboardType + NSStringPboardType + NeXT RTFD pasteboard type + NeXT Rich Text Format v1.0 pasteboard type + NeXT TIFF v4.0 pasteboard type + WebURLsWithTitlesPboardType + public.png + public.url + public.url-name + + {{0, 37}, {480, 323}} + + + + _NS:9 + + + + + + + + + + + YES + YES + + + + 268 + {{20, 10}, {97, 19}} + + + + _NS:9 + YES + + -2080374784 + 134217728 + Send message + + LucidaGrande + 12 + 16 + + _NS:9 + + -2038153216 + 164 + + + 400 + 75 + + + + + 268 + {{125, 10}, {86, 19}} + + + _NS:9 + YES + + -2080374784 + 134217728 + Call Handler + + _NS:9 + + -2038153216 + 164 + + + 400 + 75 + + + + {480, 360} + + + + + {{0, 0}, {1280, 778}} + {10000000000000, 10000000000000} + YES + + + AppDelegate + + + NSFontManager + + + + 256 + + Apple HTML pasteboard type + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple URL pasteboard type + Apple Web Archive pasteboard type + NSColor pasteboard type + NSFilenamesPboardType + NSStringPboardType + NeXT RTFD pasteboard type + NeXT Rich Text Format v1.0 pasteboard type + NeXT TIFF v4.0 pasteboard type + WebURLsWithTitlesPboardType + public.png + public.url + public.url-name + + {254, 200} + + + + _NS:9 + + + + YES + YES + + + + + + + terminate: + + + + 449 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + delegate + + + + 495 + + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + print: + + + + 86 + + + + runPageLayout: + + + + 87 + + + + clearRecentDocuments: + + + + 127 + + + + performClose: + + + + 193 + + + + toggleContinuousSpellChecking: + + + + 222 + + + + undo: + + + + 223 + + + + copy: + + + + 224 + + + + checkSpelling: + + + + 225 + + + + paste: + + + + 226 + + + + stopSpeaking: + + + + 227 + + + + cut: + + + + 228 + + + + showGuessPanel: + + + + 230 + + + + redo: + + + + 231 + + + + selectAll: + + + + 232 + + + + startSpeaking: + + + + 233 + + + + delete: + + + + 235 + + + + performZoom: + + + + 240 + + + + performFindPanelAction: + + + + 241 + + + + centerSelectionInVisibleArea: + + + + 245 + + + + toggleGrammarChecking: + + + + 347 + + + + toggleSmartInsertDelete: + + + + 355 + + + + toggleAutomaticQuoteSubstitution: + + + + 356 + + + + toggleAutomaticLinkDetection: + + + + 357 + + + + saveDocument: + + + + 362 + + + + revertDocumentToSaved: + + + + 364 + + + + runToolbarCustomizationPalette: + + + + 365 + + + + toggleToolbarShown: + + + + 366 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + newDocument: + + + + 373 + + + + openDocument: + + + + 374 + + + + raiseBaseline: + + + + 426 + + + + lowerBaseline: + + + + 427 + + + + copyFont: + + + + 428 + + + + subscript: + + + + 429 + + + + superscript: + + + + 430 + + + + tightenKerning: + + + + 431 + + + + underline: + + + + 432 + + + + orderFrontColorPanel: + + + + 433 + + + + useAllLigatures: + + + + 434 + + + + loosenKerning: + + + + 435 + + + + pasteFont: + + + + 436 + + + + unscript: + + + + 437 + + + + useStandardKerning: + + + + 438 + + + + useStandardLigatures: + + + + 439 + + + + turnOffLigatures: + + + + 440 + + + + turnOffKerning: + + + + 441 + + + + toggleAutomaticSpellingCorrection: + + + + 456 + + + + orderFrontSubstitutionsPanel: + + + + 458 + + + + toggleAutomaticDashSubstitution: + + + + 461 + + + + toggleAutomaticTextReplacement: + + + + 463 + + + + uppercaseWord: + + + + 464 + + + + capitalizeWord: + + + + 467 + + + + lowercaseWord: + + + + 468 + + + + pasteAsPlainText: + + + + 486 + + + + performFindPanelAction: + + + + 487 + + + + performFindPanelAction: + + + + 488 + + + + performFindPanelAction: + + + + 489 + + + + showHelp: + + + + 493 + + + + alignCenter: + + + + 518 + + + + pasteRuler: + + + + 519 + + + + toggleRuler: + + + + 520 + + + + alignRight: + + + + 521 + + + + copyRuler: + + + + 522 + + + + alignJustified: + + + + 523 + + + + alignLeft: + + + + 524 + + + + makeBaseWritingDirectionNatural: + + + + 525 + + + + makeBaseWritingDirectionLeftToRight: + + + + 526 + + + + makeBaseWritingDirectionRightToLeft: + + + + 527 + + + + makeTextWritingDirectionNatural: + + + + 528 + + + + makeTextWritingDirectionLeftToRight: + + + + 529 + + + + makeTextWritingDirectionRightToLeft: + + + + 530 + + + + performFindPanelAction: + + + + 535 + + + + addFontTrait: + + + + 421 + + + + addFontTrait: + + + + 422 + + + + modifyFont: + + + + 423 + + + + orderFrontFontPanel: + + + + 424 + + + + modifyFont: + + + + 425 + + + + window + + + + 532 + + + + webView + + + + 543 + + + + sendMessage: + + + + 555 + + + + callHandler: + + + + 556 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + + + + + + + + + + + + 19 + + + + + + + + 56 + + + + + + + + 217 + + + + + + + + 83 + + + + + + + + 81 + + + + + + + + + + + + + + + + + 75 + + + + + 78 + + + + + 72 + + + + + 82 + + + + + 124 + + + + + + + + 77 + + + + + 73 + + + + + 79 + + + + + 112 + + + + + 74 + + + + + 125 + + + + + + + + 126 + + + + + 205 + + + + + + + + + + + + + + + + + + + + + + 202 + + + + + 198 + + + + + 207 + + + + + 214 + + + + + 199 + + + + + 203 + + + + + 197 + + + + + 206 + + + + + 215 + + + + + 218 + + + + + + + + 216 + + + + + + + + 200 + + + + + + + + + + + + + 219 + + + + + 201 + + + + + 204 + + + + + 220 + + + + + + + + + + + + + 213 + + + + + 210 + + + + + 221 + + + + + 208 + + + + + 209 + + + + + 57 + + + + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + + + 144 + + + + + 129 + + + + + 143 + + + + + 236 + + + + + 131 + + + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 24 + + + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 295 + + + + + + + + 296 + + + + + + + + + 297 + + + + + 298 + + + + + 211 + + + + + + + + 212 + + + + + + + + + 195 + + + + + 196 + + + + + 346 + + + + + 348 + + + + + + + + 349 + + + + + + + + + + + + + + 350 + + + + + 351 + + + + + 354 + + + + + 371 + + + + + + + + 372 + + + + + 11 + 0 + + 11 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 5 + 0 + + 6 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 3 + 0 + + 4 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + 3 + 0 + + 3 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + + + + + + 375 + + + + + + + + 376 + + + + + + + + + 377 + + + + + + + + 388 + + + + + + + + + + + + + + + + + + + + + + + 389 + + + + + 390 + + + + + 391 + + + + + 392 + + + + + 393 + + + + + 394 + + + + + 395 + + + + + 396 + + + + + 397 + + + + + + + + 398 + + + + + + + + 399 + + + + + + + + 400 + + + + + 401 + + + + + 402 + + + + + 403 + + + + + 404 + + + + + 405 + + + + + + + + + + + + 406 + + + + + 407 + + + + + 408 + + + + + 409 + + + + + 410 + + + + + 411 + + + + + + + + + + 412 + + + + + 413 + + + + + 414 + + + + + 415 + + + + + + + + + + + 416 + + + + + 417 + + + + + 418 + + + + + 419 + + + + + 420 + + + + + 450 + + + + + + + + 451 + + + + + + + + + + 452 + + + + + 453 + + + + + 454 + + + + + 457 + + + + + 459 + + + + + 460 + + + + + 462 + + + + + 465 + + + + + 466 + + + + + 485 + + + + + 490 + + + + + + + + 491 + + + + + + + + 492 + + + + + 494 + + + + + 496 + + + + + + + + 497 + + + + + + + + + + + + + + + + + 498 + + + + + 499 + + + + + 500 + + + + + 501 + + + + + 502 + + + + + 503 + + + + + + + + 504 + + + + + 505 + + + + + 506 + + + + + 507 + + + + + 508 + + + + + + + + + + + + + + + + 509 + + + + + 510 + + + + + 511 + + + + + 512 + + + + + 513 + + + + + 514 + + + + + 515 + + + + + 516 + + + + + 517 + + + + + 534 + + + + + 536 + + + + + 8 + 0 + + 0 + 1 + + 323 + + 1000 + + 3 + 9 + 1 + + + + + + 539 + + + + + 540 + + + + + 542 + + + + + 544 + + + + + 545 + + + + + + + + 546 + + + + + 550 + + + + + 551 + + + + + + + + 552 + + + + + 554 + + + + + 557 + + + + + 558 + + + + + 559 + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{380, 496}, {480, 360}} + + + + + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + com.apple.WebKitIBPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + 559 + + + + + AppDelegate + NSObject + + id + id + + + + callHandler: + id + + + sendMessage: + id + + + + WebView + NSWindow + + + + webView + WebView + + + window + NSWindow + + + + IBProjectSource + ./Classes/AppDelegate.h + + + + NSLayoutConstraint + NSObject + + IBProjectSource + ./Classes/NSLayoutConstraint.h + + + + + 0 + IBCocoaFramework + YES + 3 + + {11, 11} + {10, 3} + + YES + + diff --git a/ExampleApp-OSX/main.m b/ExampleApp-OSX/main.m new file mode 100644 index 00000000..ae7b871a --- /dev/null +++ b/ExampleApp-OSX/main.m @@ -0,0 +1,14 @@ +// +// main.m +// ExampleApp-OSX +// +// Created by Antoine Lagadec on 07/04/13. +// Copyright (c) 2013 Antoine Lagadec. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **)argv); +} diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge_OSX.h b/WebViewJavascriptBridge/WebViewJavascriptBridge_OSX.h new file mode 100644 index 00000000..9a8b2f4f --- /dev/null +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge_OSX.h @@ -0,0 +1,20 @@ +// +// WebViewJavascriptBridge+OSX.h +// ExampleApp-OSX +// +// Created by Antoine Lagadec on 07/04/13. +// Copyright (c) 2013 Antoine Lagadec. All rights reserved. +// + +#import +#import "WebViewJavascriptBridgeAbstract.h" + +@interface WebViewJavascriptBridge : WebViewJavascriptBridgeAbstract + +@property (nonatomic, strong) WebView *webView; +@property (nonatomic, strong) id webViewDelegate; + ++ (id)bridgeForWebView:(WebView*)webView handler:(WVJBHandler)handler; ++ (id)bridgeForWebView:(WebView*)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)handler; + +@end diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge_OSX.m b/WebViewJavascriptBridge/WebViewJavascriptBridge_OSX.m new file mode 100644 index 00000000..02ee2ed2 --- /dev/null +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge_OSX.m @@ -0,0 +1,96 @@ +// +// WebViewJavascriptBridge+OSX.m +// ExampleApp-OSX +// +// Created by Antoine Lagadec on 07/04/13. +// Copyright (c) 2013 Antoine Lagadec. All rights reserved. +// + +#import "WebViewJavascriptBridge_OSX.h" + +@implementation WebViewJavascriptBridge + ++ (id)bridgeForWebView:(WebView *)webView handler:(WVJBHandler)handler { + return [self bridgeForWebView:webView webViewDelegate:nil handler:handler]; +} + ++ (id)bridgeForWebView:(WebView *)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { + WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; + bridge.messageHandler = messageHandler; + bridge.webView = webView; + bridge.webViewDelegate = webViewDelegate; + bridge.messageHandlers = [NSMutableDictionary dictionary]; + [bridge reset]; + + bridge.webView.frameLoadDelegate = bridge; + bridge.webView.resourceLoadDelegate = bridge; + bridge.webView.policyDelegate = bridge; + + return bridge; +} + +- (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame +{ + if (webView != self.webView) { return; } + + if (![[self.webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { + NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; + NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; + [self.webView stringByEvaluatingJavaScriptFromString:js]; + } + + if (self.startupMessageQueue) { + for (id queuedMessage in self.startupMessageQueue) { + [self _dispatchMessage:queuedMessage]; + } + self.startupMessageQueue = nil; + } + + if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)]) { + [self.webViewDelegate webView:webView didFinishLoadForFrame:frame]; + } +} + +- (void)webView:(WebView *)webView didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { + if (webView != self.webView) { return; } + if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) { + [self.webViewDelegate webView:self.webView didFailLoadWithError:error forFrame:frame]; + } +} + +- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener +{ + if (webView != self.webView) { [listener use]; } + NSURL *url = [request URL]; + if ([[url scheme] isEqualToString:kCustomProtocolScheme]) { + if ([[url host] isEqualToString:kQueueHasMessage]) { + [self _flushMessageQueue]; + } else { + NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", kCustomProtocolScheme, [url path]); + } + [listener ignore]; + } else if ([self.webView resourceLoadDelegate] + && [self.webViewDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:request:frame:decisionListener:)]) { + [self.webViewDelegate webView:webView decidePolicyForNavigationAction:actionInformation request:request frame:frame decisionListener:listener]; + } else { + [listener use]; + } +} + +- (void)webView:(WebView *)webView didCommitLoadForFrame:(WebFrame *)frame { + if (webView != self.webView) { return; } + if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didCommitLoadForFrame:)]) { + [self.webViewDelegate webView:webView didCommitLoadForFrame:frame]; + } +} + +- (NSURLRequest *)webView:(WebView *)webView resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource { + if (webView != self.webView) { return request; } + if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) { + return [self.webViewDelegate webView:webView resource:identifier willSendRequest:request redirectResponse:redirectResponse fromDataSource:dataSource]; + } + + return request; +} + +@end From 23647a1b20faa0a33934a500de13f296d4b56e2a Mon Sep 17 00:00:00 2001 From: Antoine Lagadec Date: Sun, 7 Apr 2013 15:33:33 +0200 Subject: [PATCH 010/285] Add a workspace for testing facility --- ExampleApp-OSX.xcodeproj/project.pbxproj | 56 +++++++--------- ExampleApp-OSX/en.lproj/Credits.rtf | 29 -------- ExampleApp-iOS.xcodeproj/project.pbxproj | 58 +++++++++------- ExampleApp-iOS/ExampleApp.html | 66 ------------------- .../ExampleApp.html => ExampleApp.html | 0 .../contents.xcworkspacedata | 10 +++ 6 files changed, 65 insertions(+), 154 deletions(-) delete mode 100644 ExampleApp-OSX/en.lproj/Credits.rtf delete mode 100644 ExampleApp-iOS/ExampleApp.html rename ExampleApp-OSX/ExampleApp.html => ExampleApp.html (100%) create mode 100644 WebViewJavascriptBridge.xcworkspace/contents.xcworkspacedata diff --git a/ExampleApp-OSX.xcodeproj/project.pbxproj b/ExampleApp-OSX.xcodeproj/project.pbxproj index 94d32ce7..16b0d16b 100644 --- a/ExampleApp-OSX.xcodeproj/project.pbxproj +++ b/ExampleApp-OSX.xcodeproj/project.pbxproj @@ -10,14 +10,13 @@ 2CA045DA171178E5006DEE8B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CA045D9171178E5006DEE8B /* Cocoa.framework */; }; 2CA045E4171178E6006DEE8B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045E2171178E6006DEE8B /* InfoPlist.strings */; }; 2CA045E6171178E6006DEE8B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045E5171178E6006DEE8B /* main.m */; }; - 2CA045EA171178E6006DEE8B /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045E8171178E6006DEE8B /* Credits.rtf */; }; 2CA045ED171178E6006DEE8B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045EC171178E6006DEE8B /* AppDelegate.m */; }; 2CA045F0171178E6006DEE8B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045EE171178E6006DEE8B /* MainMenu.xib */; }; - 2CA045FE17117A69006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045FC17117A69006DEE8B /* WebViewJavascriptBridge.js.txt */; }; - 2CA0460317117A84006DEE8B /* WebViewJavascriptBridge_OSX.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA0460217117A84006DEE8B /* WebViewJavascriptBridge_OSX.m */; }; 2CA0460517117B56006DEE8B /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CA0460417117B56006DEE8B /* WebKit.framework */; }; - 2CA0460A17118B08006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA0460917118B08006DEE8B /* ExampleApp.html */; }; - 2CA046161711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA046151711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.m */; }; + 2CA046531711AC29006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CA0464C1711AC29006DEE8B /* WebViewJavascriptBridge.js.txt */; }; + 2CA046551711AC29006DEE8B /* WebViewJavascriptBridge_OSX.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA046501711AC29006DEE8B /* WebViewJavascriptBridge_OSX.m */; }; + 2CA046561711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA046521711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.m */; }; + 2CA0465E1711AC96006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA0465D1711AC96006DEE8B /* ExampleApp.html */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -30,17 +29,16 @@ 2CA045E3171178E6006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 2CA045E5171178E6006DEE8B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 2CA045E7171178E6006DEE8B /* ExampleApp-OSX-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ExampleApp-OSX-Prefix.pch"; sourceTree = ""; }; - 2CA045E9171178E6006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; 2CA045EB171178E6006DEE8B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 2CA045EC171178E6006DEE8B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 2CA045EF171178E6006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; - 2CA045FC17117A69006DEE8B /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; - 2CA0460117117A84006DEE8B /* WebViewJavascriptBridge_OSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_OSX.h; sourceTree = ""; }; - 2CA0460217117A84006DEE8B /* WebViewJavascriptBridge_OSX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_OSX.m; sourceTree = ""; }; 2CA0460417117B56006DEE8B /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; - 2CA0460917118B08006DEE8B /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = ""; }; - 2CA046141711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; - 2CA046151711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; + 2CA0464C1711AC29006DEE8B /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; + 2CA0464F1711AC29006DEE8B /* WebViewJavascriptBridge_OSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_OSX.h; sourceTree = ""; }; + 2CA046501711AC29006DEE8B /* WebViewJavascriptBridge_OSX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_OSX.m; sourceTree = ""; }; + 2CA046511711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; + 2CA046521711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; + 2CA0465D1711AC96006DEE8B /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file; name = ExampleApp.html; path = ../ExampleApp.html; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -96,11 +94,11 @@ 2CA045DF171178E5006DEE8B /* ExampleApp-OSX */ = { isa = PBXGroup; children = ( + 2CA0465D1711AC96006DEE8B /* ExampleApp.html */, + 2CA0464B1711AC29006DEE8B /* WebViewJavascriptBridge */, 2CA045EB171178E6006DEE8B /* AppDelegate.h */, 2CA045EC171178E6006DEE8B /* AppDelegate.m */, 2CA045EE171178E6006DEE8B /* MainMenu.xib */, - 2CA0460917118B08006DEE8B /* ExampleApp.html */, - 2CA045FA17117A69006DEE8B /* WebViewJavascriptBridge */, 2CA045E0171178E6006DEE8B /* Supporting Files */, ); path = "ExampleApp-OSX"; @@ -113,19 +111,18 @@ 2CA045E2171178E6006DEE8B /* InfoPlist.strings */, 2CA045E5171178E6006DEE8B /* main.m */, 2CA045E7171178E6006DEE8B /* ExampleApp-OSX-Prefix.pch */, - 2CA045E8171178E6006DEE8B /* Credits.rtf */, ); name = "Supporting Files"; sourceTree = ""; }; - 2CA045FA17117A69006DEE8B /* WebViewJavascriptBridge */ = { + 2CA0464B1711AC29006DEE8B /* WebViewJavascriptBridge */ = { isa = PBXGroup; children = ( - 2CA046141711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.h */, - 2CA046151711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.m */, - 2CA045FC17117A69006DEE8B /* WebViewJavascriptBridge.js.txt */, - 2CA0460117117A84006DEE8B /* WebViewJavascriptBridge_OSX.h */, - 2CA0460217117A84006DEE8B /* WebViewJavascriptBridge_OSX.m */, + 2CA0464C1711AC29006DEE8B /* WebViewJavascriptBridge.js.txt */, + 2CA0464F1711AC29006DEE8B /* WebViewJavascriptBridge_OSX.h */, + 2CA046501711AC29006DEE8B /* WebViewJavascriptBridge_OSX.m */, + 2CA046511711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.h */, + 2CA046521711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.m */, ); path = WebViewJavascriptBridge; sourceTree = SOURCE_ROOT; @@ -182,10 +179,9 @@ buildActionMask = 2147483647; files = ( 2CA045E4171178E6006DEE8B /* InfoPlist.strings in Resources */, - 2CA045EA171178E6006DEE8B /* Credits.rtf in Resources */, 2CA045F0171178E6006DEE8B /* MainMenu.xib in Resources */, - 2CA045FE17117A69006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */, - 2CA0460A17118B08006DEE8B /* ExampleApp.html in Resources */, + 2CA046531711AC29006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */, + 2CA0465E1711AC96006DEE8B /* ExampleApp.html in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -198,8 +194,8 @@ files = ( 2CA045E6171178E6006DEE8B /* main.m in Sources */, 2CA045ED171178E6006DEE8B /* AppDelegate.m in Sources */, - 2CA0460317117A84006DEE8B /* WebViewJavascriptBridge_OSX.m in Sources */, - 2CA046161711A1CC006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */, + 2CA046551711AC29006DEE8B /* WebViewJavascriptBridge_OSX.m in Sources */, + 2CA046561711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -214,14 +210,6 @@ name = InfoPlist.strings; sourceTree = ""; }; - 2CA045E8171178E6006DEE8B /* Credits.rtf */ = { - isa = PBXVariantGroup; - children = ( - 2CA045E9171178E6006DEE8B /* en */, - ); - name = Credits.rtf; - sourceTree = ""; - }; 2CA045EE171178E6006DEE8B /* MainMenu.xib */ = { isa = PBXVariantGroup; children = ( diff --git a/ExampleApp-OSX/en.lproj/Credits.rtf b/ExampleApp-OSX/en.lproj/Credits.rtf deleted file mode 100644 index 46576ef2..00000000 --- a/ExampleApp-OSX/en.lproj/Credits.rtf +++ /dev/null @@ -1,29 +0,0 @@ -{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} -{\colortbl;\red255\green255\blue255;} -\paperw9840\paperh8400 -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural - -\f0\b\fs24 \cf0 Engineering: -\b0 \ - Some people\ -\ - -\b Human Interface Design: -\b0 \ - Some other people\ -\ - -\b Testing: -\b0 \ - Hopefully not nobody\ -\ - -\b Documentation: -\b0 \ - Whoever\ -\ - -\b With special thanks to: -\b0 \ - Mom\ -} diff --git a/ExampleApp-iOS.xcodeproj/project.pbxproj b/ExampleApp-iOS.xcodeproj/project.pbxproj index 455727cb..8338241b 100644 --- a/ExampleApp-iOS.xcodeproj/project.pbxproj +++ b/ExampleApp-iOS.xcodeproj/project.pbxproj @@ -8,12 +8,12 @@ /* Begin PBXBuildFile section */ 2CA045BF17117439006DEE8B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045B717117439006DEE8B /* InfoPlist.strings */; }; - 2CA045C117117439006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045BB17117439006DEE8B /* ExampleApp.html */; }; 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */; }; 2CA045C317117439006DEE8B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BE17117439006DEE8B /* main.m */; }; - 2CA045C81711745D006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045C61711745D006DEE8B /* WebViewJavascriptBridge.js.txt */; }; - 2CA045C91711745D006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045C71711745D006DEE8B /* WebViewJavascriptBridgeAbstract.m */; }; - 2CA0460817117BF9006DEE8B /* WebViewJavascriptBridge_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA0460717117BF9006DEE8B /* WebViewJavascriptBridge_iOS.m */; }; + 2CA0465C1711AC8E006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */; }; + 2CA046671711ACC2006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CA046601711ACC2006DEE8B /* WebViewJavascriptBridge.js.txt */; }; + 2CA046681711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA046621711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.m */; }; + 2CA0466A1711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA046661711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.m */; }; 2CEB3EC01602563600548120 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EBF1602563600548120 /* UIKit.framework */; }; 2CEB3EC21602563600548120 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EC11602563600548120 /* Foundation.framework */; }; 2CEB3EC41602563600548120 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EC31602563600548120 /* CoreGraphics.framework */; }; @@ -24,15 +24,15 @@ 2CA045B817117439006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 2CA045B917117439006DEE8B /* ExampleApp-iOS-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ExampleApp-iOS-Info.plist"; sourceTree = ""; }; 2CA045BA17117439006DEE8B /* ExampleApp-iOS-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ExampleApp-iOS-Prefix.pch"; sourceTree = ""; }; - 2CA045BB17117439006DEE8B /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = ""; }; 2CA045BC17117439006DEE8B /* ExampleAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExampleAppDelegate.h; sourceTree = ""; }; 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleAppDelegate.m; sourceTree = ""; }; 2CA045BE17117439006DEE8B /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 2CA045C51711745D006DEE8B /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; - 2CA045C61711745D006DEE8B /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; - 2CA045C71711745D006DEE8B /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; - 2CA0460617117BF9006DEE8B /* WebViewJavascriptBridge_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_iOS.h; sourceTree = ""; }; - 2CA0460717117BF9006DEE8B /* WebViewJavascriptBridge_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_iOS.m; sourceTree = ""; }; + 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = SOURCE_ROOT; }; + 2CA046601711ACC2006DEE8B /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; + 2CA046611711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_iOS.h; sourceTree = ""; }; + 2CA046621711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_iOS.m; sourceTree = ""; }; + 2CA046651711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; + 2CA046661711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; 2CEB3EBB1602563600548120 /* ExampleApp-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ExampleApp-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 2CEB3EBF1602563600548120 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 2CEB3EC11602563600548120 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -57,26 +57,34 @@ 2CA045B617117439006DEE8B /* ExampleApp-iOS */ = { isa = PBXGroup; children = ( - 2CA045C41711745D006DEE8B /* WebViewJavascriptBridge */, + 2CA0465F1711ACC2006DEE8B /* WebViewJavascriptBridge */, + 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */, + 2CA045BC17117439006DEE8B /* ExampleAppDelegate.h */, + 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */, + 2CA046211711A94E006DEE8B /* Supporting Files */, + ); + path = "ExampleApp-iOS"; + sourceTree = ""; + }; + 2CA046211711A94E006DEE8B /* Supporting Files */ = { + isa = PBXGroup; + children = ( 2CA045B717117439006DEE8B /* InfoPlist.strings */, 2CA045B917117439006DEE8B /* ExampleApp-iOS-Info.plist */, 2CA045BA17117439006DEE8B /* ExampleApp-iOS-Prefix.pch */, - 2CA045BB17117439006DEE8B /* ExampleApp.html */, - 2CA045BC17117439006DEE8B /* ExampleAppDelegate.h */, - 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */, 2CA045BE17117439006DEE8B /* main.m */, ); - path = "ExampleApp-iOS"; + name = "Supporting Files"; sourceTree = ""; }; - 2CA045C41711745D006DEE8B /* WebViewJavascriptBridge */ = { + 2CA0465F1711ACC2006DEE8B /* WebViewJavascriptBridge */ = { isa = PBXGroup; children = ( - 2CA045C51711745D006DEE8B /* WebViewJavascriptBridgeAbstract.h */, - 2CA045C61711745D006DEE8B /* WebViewJavascriptBridge.js.txt */, - 2CA045C71711745D006DEE8B /* WebViewJavascriptBridgeAbstract.m */, - 2CA0460617117BF9006DEE8B /* WebViewJavascriptBridge_iOS.h */, - 2CA0460717117BF9006DEE8B /* WebViewJavascriptBridge_iOS.m */, + 2CA046601711ACC2006DEE8B /* WebViewJavascriptBridge.js.txt */, + 2CA046611711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.h */, + 2CA046621711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.m */, + 2CA046651711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.h */, + 2CA046661711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.m */, ); path = WebViewJavascriptBridge; sourceTree = SOURCE_ROOT; @@ -162,8 +170,8 @@ files = ( 2CF988CE170E0BA500CA0CC7 /* Default-568h@2x.png in Resources */, 2CA045BF17117439006DEE8B /* InfoPlist.strings in Resources */, - 2CA045C117117439006DEE8B /* ExampleApp.html in Resources */, - 2CA045C81711745D006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */, + 2CA0465C1711AC8E006DEE8B /* ExampleApp.html in Resources */, + 2CA046671711ACC2006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -176,8 +184,8 @@ files = ( 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */, 2CA045C317117439006DEE8B /* main.m in Sources */, - 2CA045C91711745D006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */, - 2CA0460817117BF9006DEE8B /* WebViewJavascriptBridge_iOS.m in Sources */, + 2CA046681711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.m in Sources */, + 2CA0466A1711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ExampleApp-iOS/ExampleApp.html b/ExampleApp-iOS/ExampleApp.html deleted file mode 100644 index 5a12d4d2..00000000 --- a/ExampleApp-iOS/ExampleApp.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - -

WebViewJavascriptBridge Demo

- -
- diff --git a/ExampleApp-OSX/ExampleApp.html b/ExampleApp.html similarity index 100% rename from ExampleApp-OSX/ExampleApp.html rename to ExampleApp.html diff --git a/WebViewJavascriptBridge.xcworkspace/contents.xcworkspacedata b/WebViewJavascriptBridge.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..2b523419 --- /dev/null +++ b/WebViewJavascriptBridge.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + From c4fbcd6182be55c17f2bdad43b72ac5ca554ca70 Mon Sep 17 00:00:00 2001 From: Antoine Lagadec Date: Sun, 7 Apr 2013 15:53:56 +0200 Subject: [PATCH 011/285] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b1ead06e..edccdc15 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,13 @@ WebViewJavascriptBridge is used by a range of companies and projects. This list - [EverTrue](http://www.evertrue.com/) - [Game Insight](http://www.game-insight.com/) - [Altralogica](http://www.altralogica.it) +- [Sush.io](http://www.sush.io) - Flutterby Labs - JD Media's [鼎盛中华](https://itunes.apple.com/us/app/ding-sheng-zhong-hua/id537273940?mt=8) Are you using WebViewJavascript at your company? Add it and send us a pull request! -Setup & Examples +Setup & Examples (iOS) ---------------- Just open the Xcode project and hit run to see ExampleApp run. @@ -28,10 +29,11 @@ To use a WebViewJavascriptBridge in your own project: 1) Drag the `WebViewJavascriptBridge` folder into your project. - In the dialog that appears, uncheck "Copy items into destination group's folder" and select "Create groups for any folders" + - Delete OSX files. 2) Import the header file: - #import "WebViewJavascriptBridge.h" + #import "WebViewJavascriptBridge_iOS.h" 3) Instantiate a UIWebView and a WebViewJavascriptBridge: From 5775ebb7533096d0d3d1d509ef02f81be5ebe30d Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Thu, 18 Apr 2013 17:10:32 -0700 Subject: [PATCH 012/285] add disableLogging --- WebViewJavascriptBridge/WebViewJavascriptBridge.h | 1 + WebViewJavascriptBridge/WebViewJavascriptBridge.m | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.h b/WebViewJavascriptBridge/WebViewJavascriptBridge.h index 7eeaee3d..c052ee33 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.h +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.h @@ -7,6 +7,7 @@ typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); + (id)bridgeForWebView:(UIWebView*)webView handler:(WVJBHandler)handler; + (id)bridgeForWebView:(UIWebView*)webView webViewDelegate:(id )webViewDelegate handler:(WVJBHandler)handler; + (void)enableLogging; ++ (void)disableLogging; - (void)send:(id)message; - (void)send:(id)message responseCallback:(WVJBResponseCallback)responseCallback; - (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler; diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index bf5f9583..ae375fb1 100755 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -45,8 +45,9 @@ + (id)bridgeForWebView:(UIWebView *)webView webViewDelegate:(id Date: Tue, 23 Apr 2013 18:11:21 -0700 Subject: [PATCH 013/285] Reorganize files so that: 1) including WVJB in an OSX or iOS project is simply dragging the one corresponding folder into your project (WebViewJavascriptBridge_iOS/OSX respectively), and 2) put all the example app contents in a single directory --- .../ExampleApp-OSX.xcodeproj}/project.pbxproj | 51 +++++++++------- .../ExampleApp-OSX}/AppDelegate.h | 0 .../ExampleApp-OSX}/AppDelegate.m | 0 .../ExampleApp-OSX}/ExampleApp-OSX-Info.plist | 0 .../ExampleApp-OSX}/ExampleApp-OSX-Prefix.pch | 0 .../en.lproj/InfoPlist.strings | 0 .../ExampleApp-OSX}/en.lproj/MainMenu.xib | 0 .../ExampleApp-OSX}/main.m | 0 .../ExampleApp-iOS.xcodeproj}/project.pbxproj | 57 ++++++++++-------- .../ExampleApp-iOS/Default-568h@2x.png | Bin .../ExampleApp-iOS}/ExampleApp-iOS-Info.plist | 0 .../ExampleApp-iOS}/ExampleApp-iOS-Prefix.pch | 0 .../ExampleApp-iOS}/ExampleAppDelegate.h | 0 .../ExampleApp-iOS}/ExampleAppDelegate.m | 0 .../en.lproj/InfoPlist.strings | 0 .../ExampleApp-iOS}/main.m | 0 .../ExampleApp.html | 0 .../WebViewJavascriptBridge.js.txt | 0 .../WebViewJavascriptBridgeAbstract.h | 0 .../WebViewJavascriptBridgeAbstract.m | 0 .../WebViewJavascriptAbstract | 1 + .../WebViewJavascriptBridge_OSX.h | 0 .../WebViewJavascriptBridge_OSX.m | 0 .../WebViewJavascriptAbstract | 1 + .../WebViewJavascriptBridge_iOS.h | 0 .../WebViewJavascriptBridge_iOS.m | 0 26 files changed, 65 insertions(+), 45 deletions(-) rename {ExampleApp-OSX.xcodeproj => Example Apps/ExampleApp-OSX.xcodeproj}/project.pbxproj (86%) rename {ExampleApp-OSX => Example Apps/ExampleApp-OSX}/AppDelegate.h (100%) rename {ExampleApp-OSX => Example Apps/ExampleApp-OSX}/AppDelegate.m (100%) rename {ExampleApp-OSX => Example Apps/ExampleApp-OSX}/ExampleApp-OSX-Info.plist (100%) rename {ExampleApp-OSX => Example Apps/ExampleApp-OSX}/ExampleApp-OSX-Prefix.pch (100%) rename {ExampleApp-OSX => Example Apps/ExampleApp-OSX}/en.lproj/InfoPlist.strings (100%) rename {ExampleApp-OSX => Example Apps/ExampleApp-OSX}/en.lproj/MainMenu.xib (100%) rename {ExampleApp-OSX => Example Apps/ExampleApp-OSX}/main.m (100%) rename {ExampleApp-iOS.xcodeproj => Example Apps/ExampleApp-iOS.xcodeproj}/project.pbxproj (83%) rename Default-568h@2x.png => Example Apps/ExampleApp-iOS/Default-568h@2x.png (100%) rename {ExampleApp-iOS => Example Apps/ExampleApp-iOS}/ExampleApp-iOS-Info.plist (100%) rename {ExampleApp-iOS => Example Apps/ExampleApp-iOS}/ExampleApp-iOS-Prefix.pch (100%) rename {ExampleApp-iOS => Example Apps/ExampleApp-iOS}/ExampleAppDelegate.h (100%) rename {ExampleApp-iOS => Example Apps/ExampleApp-iOS}/ExampleAppDelegate.m (100%) rename {ExampleApp-iOS => Example Apps/ExampleApp-iOS}/en.lproj/InfoPlist.strings (100%) rename {ExampleApp-iOS => Example Apps/ExampleApp-iOS}/main.m (100%) rename ExampleApp.html => Example Apps/ExampleApp.html (100%) rename {WebViewJavascriptBridge => WebViewJavascriptBridgeAbstract}/WebViewJavascriptBridge.js.txt (100%) rename {WebViewJavascriptBridge => WebViewJavascriptBridgeAbstract}/WebViewJavascriptBridgeAbstract.h (100%) rename {WebViewJavascriptBridge => WebViewJavascriptBridgeAbstract}/WebViewJavascriptBridgeAbstract.m (100%) create mode 120000 WebViewJavascriptBridge_OSX/WebViewJavascriptAbstract rename {WebViewJavascriptBridge => WebViewJavascriptBridge_OSX}/WebViewJavascriptBridge_OSX.h (100%) rename {WebViewJavascriptBridge => WebViewJavascriptBridge_OSX}/WebViewJavascriptBridge_OSX.m (100%) create mode 120000 WebViewJavascriptBridge_iOS/WebViewJavascriptAbstract rename {WebViewJavascriptBridge => WebViewJavascriptBridge_iOS}/WebViewJavascriptBridge_iOS.h (100%) rename {WebViewJavascriptBridge => WebViewJavascriptBridge_iOS}/WebViewJavascriptBridge_iOS.m (100%) diff --git a/ExampleApp-OSX.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj similarity index 86% rename from ExampleApp-OSX.xcodeproj/project.pbxproj rename to Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj index 16b0d16b..5e5e13ab 100644 --- a/ExampleApp-OSX.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj @@ -13,10 +13,10 @@ 2CA045ED171178E6006DEE8B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045EC171178E6006DEE8B /* AppDelegate.m */; }; 2CA045F0171178E6006DEE8B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045EE171178E6006DEE8B /* MainMenu.xib */; }; 2CA0460517117B56006DEE8B /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CA0460417117B56006DEE8B /* WebKit.framework */; }; - 2CA046531711AC29006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CA0464C1711AC29006DEE8B /* WebViewJavascriptBridge.js.txt */; }; - 2CA046551711AC29006DEE8B /* WebViewJavascriptBridge_OSX.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA046501711AC29006DEE8B /* WebViewJavascriptBridge_OSX.m */; }; - 2CA046561711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA046521711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.m */; }; 2CA0465E1711AC96006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA0465D1711AC96006DEE8B /* ExampleApp.html */; }; + 2CAB8695172766DF00BD9ED1 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CAB8690172766DF00BD9ED1 /* WebViewJavascriptBridge.js.txt */; }; + 2CAB8696172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CAB8692172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.m */; }; + 2CAB8697172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CAB8694172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -33,12 +33,12 @@ 2CA045EC171178E6006DEE8B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 2CA045EF171178E6006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; 2CA0460417117B56006DEE8B /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; - 2CA0464C1711AC29006DEE8B /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; - 2CA0464F1711AC29006DEE8B /* WebViewJavascriptBridge_OSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_OSX.h; sourceTree = ""; }; - 2CA046501711AC29006DEE8B /* WebViewJavascriptBridge_OSX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_OSX.m; sourceTree = ""; }; - 2CA046511711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; - 2CA046521711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; - 2CA0465D1711AC96006DEE8B /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file; name = ExampleApp.html; path = ../ExampleApp.html; sourceTree = ""; }; + 2CA0465D1711AC96006DEE8B /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = ExampleApp.html; path = ../ExampleApp.html; sourceTree = ""; }; + 2CAB8690172766DF00BD9ED1 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; + 2CAB8691172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; + 2CAB8692172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; + 2CAB8693172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_OSX.h; sourceTree = ""; }; + 2CAB8694172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_OSX.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -95,10 +95,10 @@ isa = PBXGroup; children = ( 2CA0465D1711AC96006DEE8B /* ExampleApp.html */, - 2CA0464B1711AC29006DEE8B /* WebViewJavascriptBridge */, 2CA045EB171178E6006DEE8B /* AppDelegate.h */, 2CA045EC171178E6006DEE8B /* AppDelegate.m */, 2CA045EE171178E6006DEE8B /* MainMenu.xib */, + 2CAB868E172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX */, 2CA045E0171178E6006DEE8B /* Supporting Files */, ); path = "ExampleApp-OSX"; @@ -115,17 +115,26 @@ name = "Supporting Files"; sourceTree = ""; }; - 2CA0464B1711AC29006DEE8B /* WebViewJavascriptBridge */ = { + 2CAB868E172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX */ = { isa = PBXGroup; children = ( - 2CA0464C1711AC29006DEE8B /* WebViewJavascriptBridge.js.txt */, - 2CA0464F1711AC29006DEE8B /* WebViewJavascriptBridge_OSX.h */, - 2CA046501711AC29006DEE8B /* WebViewJavascriptBridge_OSX.m */, - 2CA046511711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.h */, - 2CA046521711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.m */, + 2CAB868F172766DF00BD9ED1 /* WebViewJavascriptAbstract */, + 2CAB8693172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.h */, + 2CAB8694172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.m */, ); - path = WebViewJavascriptBridge; - sourceTree = SOURCE_ROOT; + name = WebViewJavascriptBridge_OSX; + path = ../../WebViewJavascriptBridge_OSX; + sourceTree = ""; + }; + 2CAB868F172766DF00BD9ED1 /* WebViewJavascriptAbstract */ = { + isa = PBXGroup; + children = ( + 2CAB8690172766DF00BD9ED1 /* WebViewJavascriptBridge.js.txt */, + 2CAB8691172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.h */, + 2CAB8692172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.m */, + ); + path = WebViewJavascriptAbstract; + sourceTree = ""; }; /* End PBXGroup section */ @@ -180,8 +189,8 @@ files = ( 2CA045E4171178E6006DEE8B /* InfoPlist.strings in Resources */, 2CA045F0171178E6006DEE8B /* MainMenu.xib in Resources */, - 2CA046531711AC29006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */, 2CA0465E1711AC96006DEE8B /* ExampleApp.html in Resources */, + 2CAB8695172766DF00BD9ED1 /* WebViewJavascriptBridge.js.txt in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -194,8 +203,8 @@ files = ( 2CA045E6171178E6006DEE8B /* main.m in Sources */, 2CA045ED171178E6006DEE8B /* AppDelegate.m in Sources */, - 2CA046551711AC29006DEE8B /* WebViewJavascriptBridge_OSX.m in Sources */, - 2CA046561711AC29006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */, + 2CAB8696172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.m in Sources */, + 2CAB8697172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ExampleApp-OSX/AppDelegate.h b/Example Apps/ExampleApp-OSX/AppDelegate.h similarity index 100% rename from ExampleApp-OSX/AppDelegate.h rename to Example Apps/ExampleApp-OSX/AppDelegate.h diff --git a/ExampleApp-OSX/AppDelegate.m b/Example Apps/ExampleApp-OSX/AppDelegate.m similarity index 100% rename from ExampleApp-OSX/AppDelegate.m rename to Example Apps/ExampleApp-OSX/AppDelegate.m diff --git a/ExampleApp-OSX/ExampleApp-OSX-Info.plist b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist similarity index 100% rename from ExampleApp-OSX/ExampleApp-OSX-Info.plist rename to Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist diff --git a/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch similarity index 100% rename from ExampleApp-OSX/ExampleApp-OSX-Prefix.pch rename to Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch diff --git a/ExampleApp-OSX/en.lproj/InfoPlist.strings b/Example Apps/ExampleApp-OSX/en.lproj/InfoPlist.strings similarity index 100% rename from ExampleApp-OSX/en.lproj/InfoPlist.strings rename to Example Apps/ExampleApp-OSX/en.lproj/InfoPlist.strings diff --git a/ExampleApp-OSX/en.lproj/MainMenu.xib b/Example Apps/ExampleApp-OSX/en.lproj/MainMenu.xib similarity index 100% rename from ExampleApp-OSX/en.lproj/MainMenu.xib rename to Example Apps/ExampleApp-OSX/en.lproj/MainMenu.xib diff --git a/ExampleApp-OSX/main.m b/Example Apps/ExampleApp-OSX/main.m similarity index 100% rename from ExampleApp-OSX/main.m rename to Example Apps/ExampleApp-OSX/main.m diff --git a/ExampleApp-iOS.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj similarity index 83% rename from ExampleApp-iOS.xcodeproj/project.pbxproj rename to Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj index 8338241b..6a694a05 100644 --- a/ExampleApp-iOS.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj @@ -11,13 +11,13 @@ 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */; }; 2CA045C317117439006DEE8B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BE17117439006DEE8B /* main.m */; }; 2CA0465C1711AC8E006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */; }; - 2CA046671711ACC2006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CA046601711ACC2006DEE8B /* WebViewJavascriptBridge.js.txt */; }; - 2CA046681711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA046621711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.m */; }; - 2CA0466A1711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA046661711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.m */; }; + 2CAB868B172766B000BD9ED1 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CAB8686172766B000BD9ED1 /* WebViewJavascriptBridge.js.txt */; }; + 2CAB868C172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CAB8688172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.m */; }; + 2CAB868D172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CAB868A172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.m */; }; + 2CAB869B1727684300BD9ED1 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2CAB869A1727684300BD9ED1 /* Default-568h@2x.png */; }; 2CEB3EC01602563600548120 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EBF1602563600548120 /* UIKit.framework */; }; 2CEB3EC21602563600548120 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EC11602563600548120 /* Foundation.framework */; }; 2CEB3EC41602563600548120 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EC31602563600548120 /* CoreGraphics.framework */; }; - 2CF988CE170E0BA500CA0CC7 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2CF988CD170E0BA500CA0CC7 /* Default-568h@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -28,16 +28,16 @@ 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleAppDelegate.m; sourceTree = ""; }; 2CA045BE17117439006DEE8B /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = SOURCE_ROOT; }; - 2CA046601711ACC2006DEE8B /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; - 2CA046611711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_iOS.h; sourceTree = ""; }; - 2CA046621711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_iOS.m; sourceTree = ""; }; - 2CA046651711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; - 2CA046661711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; + 2CAB8686172766B000BD9ED1 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; + 2CAB8687172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; + 2CAB8688172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; + 2CAB8689172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_iOS.h; sourceTree = ""; }; + 2CAB868A172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_iOS.m; sourceTree = ""; }; + 2CAB869A1727684300BD9ED1 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "ExampleApp-iOS/Default-568h@2x.png"; sourceTree = ""; }; 2CEB3EBB1602563600548120 /* ExampleApp-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ExampleApp-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 2CEB3EBF1602563600548120 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 2CEB3EC11602563600548120 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 2CEB3EC31602563600548120 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - 2CF988CD170E0BA500CA0CC7 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -57,10 +57,10 @@ 2CA045B617117439006DEE8B /* ExampleApp-iOS */ = { isa = PBXGroup; children = ( - 2CA0465F1711ACC2006DEE8B /* WebViewJavascriptBridge */, 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */, 2CA045BC17117439006DEE8B /* ExampleAppDelegate.h */, 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */, + 2CAB8684172766B000BD9ED1 /* WebViewJavascriptBridge_iOS */, 2CA046211711A94E006DEE8B /* Supporting Files */, ); path = "ExampleApp-iOS"; @@ -77,22 +77,31 @@ name = "Supporting Files"; sourceTree = ""; }; - 2CA0465F1711ACC2006DEE8B /* WebViewJavascriptBridge */ = { + 2CAB8684172766B000BD9ED1 /* WebViewJavascriptBridge_iOS */ = { isa = PBXGroup; children = ( - 2CA046601711ACC2006DEE8B /* WebViewJavascriptBridge.js.txt */, - 2CA046611711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.h */, - 2CA046621711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.m */, - 2CA046651711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.h */, - 2CA046661711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.m */, + 2CAB8685172766B000BD9ED1 /* WebViewJavascriptAbstract */, + 2CAB8689172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.h */, + 2CAB868A172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.m */, ); - path = WebViewJavascriptBridge; - sourceTree = SOURCE_ROOT; + name = WebViewJavascriptBridge_iOS; + path = ../../WebViewJavascriptBridge_iOS; + sourceTree = ""; + }; + 2CAB8685172766B000BD9ED1 /* WebViewJavascriptAbstract */ = { + isa = PBXGroup; + children = ( + 2CAB8686172766B000BD9ED1 /* WebViewJavascriptBridge.js.txt */, + 2CAB8687172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.h */, + 2CAB8688172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.m */, + ); + path = WebViewJavascriptAbstract; + sourceTree = ""; }; 2CEB3EB01602563600548120 = { isa = PBXGroup; children = ( - 2CF988CD170E0BA500CA0CC7 /* Default-568h@2x.png */, + 2CAB869A1727684300BD9ED1 /* Default-568h@2x.png */, 2CA045B617117439006DEE8B /* ExampleApp-iOS */, 2CEB3EBE1602563600548120 /* Frameworks */, 2CEB3EBC1602563600548120 /* Products */, @@ -168,10 +177,10 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2CF988CE170E0BA500CA0CC7 /* Default-568h@2x.png in Resources */, 2CA045BF17117439006DEE8B /* InfoPlist.strings in Resources */, 2CA0465C1711AC8E006DEE8B /* ExampleApp.html in Resources */, - 2CA046671711ACC2006DEE8B /* WebViewJavascriptBridge.js.txt in Resources */, + 2CAB868B172766B000BD9ED1 /* WebViewJavascriptBridge.js.txt in Resources */, + 2CAB869B1727684300BD9ED1 /* Default-568h@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -184,8 +193,8 @@ files = ( 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */, 2CA045C317117439006DEE8B /* main.m in Sources */, - 2CA046681711ACC2006DEE8B /* WebViewJavascriptBridge_iOS.m in Sources */, - 2CA0466A1711ACC2006DEE8B /* WebViewJavascriptBridgeAbstract.m in Sources */, + 2CAB868C172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.m in Sources */, + 2CAB868D172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Default-568h@2x.png b/Example Apps/ExampleApp-iOS/Default-568h@2x.png similarity index 100% rename from Default-568h@2x.png rename to Example Apps/ExampleApp-iOS/Default-568h@2x.png diff --git a/ExampleApp-iOS/ExampleApp-iOS-Info.plist b/Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist similarity index 100% rename from ExampleApp-iOS/ExampleApp-iOS-Info.plist rename to Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist diff --git a/ExampleApp-iOS/ExampleApp-iOS-Prefix.pch b/Example Apps/ExampleApp-iOS/ExampleApp-iOS-Prefix.pch similarity index 100% rename from ExampleApp-iOS/ExampleApp-iOS-Prefix.pch rename to Example Apps/ExampleApp-iOS/ExampleApp-iOS-Prefix.pch diff --git a/ExampleApp-iOS/ExampleAppDelegate.h b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h similarity index 100% rename from ExampleApp-iOS/ExampleAppDelegate.h rename to Example Apps/ExampleApp-iOS/ExampleAppDelegate.h diff --git a/ExampleApp-iOS/ExampleAppDelegate.m b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m similarity index 100% rename from ExampleApp-iOS/ExampleAppDelegate.m rename to Example Apps/ExampleApp-iOS/ExampleAppDelegate.m diff --git a/ExampleApp-iOS/en.lproj/InfoPlist.strings b/Example Apps/ExampleApp-iOS/en.lproj/InfoPlist.strings similarity index 100% rename from ExampleApp-iOS/en.lproj/InfoPlist.strings rename to Example Apps/ExampleApp-iOS/en.lproj/InfoPlist.strings diff --git a/ExampleApp-iOS/main.m b/Example Apps/ExampleApp-iOS/main.m similarity index 100% rename from ExampleApp-iOS/main.m rename to Example Apps/ExampleApp-iOS/main.m diff --git a/ExampleApp.html b/Example Apps/ExampleApp.html similarity index 100% rename from ExampleApp.html rename to Example Apps/ExampleApp.html diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridge.js.txt similarity index 100% rename from WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt rename to WebViewJavascriptBridgeAbstract/WebViewJavascriptBridge.js.txt diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridgeAbstract.h b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h similarity index 100% rename from WebViewJavascriptBridge/WebViewJavascriptBridgeAbstract.h rename to WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridgeAbstract.m b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m similarity index 100% rename from WebViewJavascriptBridge/WebViewJavascriptBridgeAbstract.m rename to WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptAbstract b/WebViewJavascriptBridge_OSX/WebViewJavascriptAbstract new file mode 120000 index 00000000..2cb3269a --- /dev/null +++ b/WebViewJavascriptBridge_OSX/WebViewJavascriptAbstract @@ -0,0 +1 @@ +../WebViewJavascriptBridgeAbstract \ No newline at end of file diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge_OSX.h b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h similarity index 100% rename from WebViewJavascriptBridge/WebViewJavascriptBridge_OSX.h rename to WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge_OSX.m b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m similarity index 100% rename from WebViewJavascriptBridge/WebViewJavascriptBridge_OSX.m rename to WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptAbstract b/WebViewJavascriptBridge_iOS/WebViewJavascriptAbstract new file mode 120000 index 00000000..2cb3269a --- /dev/null +++ b/WebViewJavascriptBridge_iOS/WebViewJavascriptAbstract @@ -0,0 +1 @@ +../WebViewJavascriptBridgeAbstract \ No newline at end of file diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge_iOS.h b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h similarity index 100% rename from WebViewJavascriptBridge/WebViewJavascriptBridge_iOS.h rename to WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge_iOS.m b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m similarity index 100% rename from WebViewJavascriptBridge/WebViewJavascriptBridge_iOS.m rename to WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m From 0c529da77ad45f09a7d075ab55bec968da4334a3 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Tue, 23 Apr 2013 18:11:30 -0700 Subject: [PATCH 014/285] resolve compile-time warning --- .../WebViewJavascriptBridgeAbstract.h | 2 +- .../WebViewJavascriptBridgeAbstract.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h index 11864b6a..a5d3cd83 100644 --- a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h +++ b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h @@ -12,7 +12,7 @@ typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); @property (nonatomic, strong) NSMutableArray *startupMessageQueue; @property (nonatomic, strong) NSMutableDictionary *responseCallbacks; @property (nonatomic, strong) NSMutableDictionary *messageHandlers; -@property (atomic, assign) NSInteger uniqueId; +@property (atomic, assign) long uniqueId; @property (nonatomic, copy) WVJBHandler messageHandler; + (void)enableLogging; diff --git a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m index 830a5581..7e2408a2 100755 --- a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m +++ b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m @@ -51,7 +51,7 @@ - (void)_sendData:(NSDictionary *)data responseCallback:(WVJBResponseCallback)re NSMutableDictionary* message = [NSMutableDictionary dictionaryWithObject:data forKey:@"data"]; if (responseCallback) { - NSString* callbackId = [NSString stringWithFormat:@"objc_cb_%d", ++self.uniqueId]; + NSString* callbackId = [NSString stringWithFormat:@"objc_cb_%ld", ++self.uniqueId]; self.responseCallbacks[callbackId] = [responseCallback copy]; message[@"callbackId"] = callbackId; } From 8486e00c173627efdc38d9db53718146e09a4cb4 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Tue, 23 Apr 2013 18:26:42 -0700 Subject: [PATCH 015/285] update README instructions to deal with both iOS and OSX --- README.md | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index edccdc15..562b9152 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ WebViewJavascriptBridge ======================= -An iOS bridge for sending messages to and from javascript in a UIWebView. +An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews. -If you like WebViewJavascriptBridge you should also check out [WebViewProxy](https://github.com/marcuswestin/WebViewProxy). +If you like WebViewJavascriptBridge you may also want to check out [WebViewProxy](https://github.com/marcuswestin/WebViewProxy). In the Wild ----------- -WebViewJavascriptBridge is used by a range of companies and projects. This list was just started and is still very incomplete. +WebViewJavascriptBridge is used by a range of companies and projects. This list is incomplete, but feel free to add your's and send a PR. - [Yardsale](https://www.getyardsale.com/) - [EverTrue](http://www.evertrue.com/) @@ -17,27 +17,26 @@ WebViewJavascriptBridge is used by a range of companies and projects. This list - Flutterby Labs - JD Media's [鼎盛中华](https://itunes.apple.com/us/app/ding-sheng-zhong-hua/id537273940?mt=8) -Are you using WebViewJavascript at your company? Add it and send us a pull request! +Setup & Examples (iOS & OSX) +---------------------------- -Setup & Examples (iOS) ----------------- - -Just open the Xcode project and hit run to see ExampleApp run. +Start with the Example Apps/ folder. Open either the iOS or OSX project and hit run to see it in action. To use a WebViewJavascriptBridge in your own project: -1) Drag the `WebViewJavascriptBridge` folder into your project. +1) Drag the `WebViewJavascriptBridge_iOS` or `WebViewJavascriptBridge_OSX` folder into your project. - In the dialog that appears, uncheck "Copy items into destination group's folder" and select "Create groups for any folders" - - Delete OSX files. - + 2) Import the header file: + // for iOS: #import "WebViewJavascriptBridge_iOS.h" + // for OSX: + #import "WebViewJavascriptBridge_OSX.h" -3) Instantiate a UIWebView and a WebViewJavascriptBridge: +3) Instantiate WebViewJavascriptBridge with a UIWebView (iOS) or WebView (OSX): - UIWebView* webView = [[UIWebView alloc] initWithFrame:self.window.bounds]; WebViewJavascriptBridge* bridge = [WebViewJavascriptBridge bridgeForWebView:webView handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"Received message from javascript: %@", data); responseCallback(@"Right back atcha"); @@ -72,14 +71,14 @@ API Reference ### ObjC API -##### `[WebViewJavascriptBridge bridgeForWebView:(UIWebView*)webview handler:(WVJBHandler)handler]` -##### `[WebViewJavascriptBridge bridgeForWebView:(UIWebView*)webview webViewDelegate:(UIWebViewDelegate*)webViewDelegate handler:(WVJBHandler)handler]` +##### `[WebViewJavascriptBridge bridgeForWebView:(UIWebView/WebView*)webview handler:(WVJBHandler)handler]` +##### `[WebViewJavascriptBridge bridgeForWebView:(UIWebView/WebView*)webview webViewDelegate:(UIWebViewDelegate*)webViewDelegate handler:(WVJBHandler)handler]` -Create a javascript bridge for the given UIWebView. +Create a javascript bridge for the given web view. The `WVJBResponseCallback` will not be `nil` if the javascript expects a response. -Optionally, pass in `webViewDelegate:(UIWebViewDelegate*)webViewDelegate` if you need to respond to the [UIWebView's lifecycle events](http://developer.apple.com/library/ios/documentation/uikit/reference/UIWebViewDelegate_Protocol/Reference/Reference.html). +Optionally, pass in `webViewDelegate:(UIWebViewDelegate*)webViewDelegate` if you need to respond to the [web view's lifecycle events](http://developer.apple.com/library/ios/documentation/uikit/reference/UIWebViewDelegate_Protocol/Reference/Reference.html). Example: @@ -186,7 +185,7 @@ Example: iOS4 support (with JSONKit) --------------------------- -*Note*: iOS4 support has not yet been tested in v2. +*Note*: iOS4 support has not yet been tested in v2+. WebViewJavascriptBridge uses `NSJSONSerialization` by default. If you need iOS 4 support then you can use [JSONKit](https://github.com/johnezang/JSONKit/), and add `USE_JSONKIT` to the preprocessor macros for your project. From 6a5cb6530175a24fda759461825c62646d2f6ca2 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Tue, 23 Apr 2013 18:28:28 -0700 Subject: [PATCH 016/285] Add @oakho to list of contributors, and reassign copyright of entire library to include both Marcus Westin and Antoine Lagadec. --- Example Apps/ExampleApp-OSX/AppDelegate.h | 8 -------- Example Apps/ExampleApp-OSX/AppDelegate.m | 8 -------- Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist | 2 +- Example Apps/ExampleApp-OSX/main.m | 8 -------- Example Apps/ExampleApp-iOS/main.m | 8 -------- LICENSE | 2 +- README.md | 4 ++-- WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h | 8 -------- WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m | 8 -------- WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h | 8 -------- WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m | 8 -------- 11 files changed, 4 insertions(+), 68 deletions(-) diff --git a/Example Apps/ExampleApp-OSX/AppDelegate.h b/Example Apps/ExampleApp-OSX/AppDelegate.h index 96bb190a..ddbd75fd 100644 --- a/Example Apps/ExampleApp-OSX/AppDelegate.h +++ b/Example Apps/ExampleApp-OSX/AppDelegate.h @@ -1,11 +1,3 @@ -// -// AppDelegate.h -// ExampleApp-OSX -// -// Created by Antoine Lagadec on 07/04/13. -// Copyright (c) 2013 Antoine Lagadec. All rights reserved. -// - #import #import "WebViewJavascriptBridge_OSX.h" diff --git a/Example Apps/ExampleApp-OSX/AppDelegate.m b/Example Apps/ExampleApp-OSX/AppDelegate.m index ed31863b..4db9997b 100644 --- a/Example Apps/ExampleApp-OSX/AppDelegate.m +++ b/Example Apps/ExampleApp-OSX/AppDelegate.m @@ -1,11 +1,3 @@ -// -// AppDelegate.m -// ExampleApp-OSX -// -// Created by Antoine Lagadec on 07/04/13. -// Copyright (c) 2013 Antoine Lagadec. All rights reserved. -// - #import "AppDelegate.h" @implementation AppDelegate diff --git a/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist index 5a46a8d8..18703404 100644 --- a/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist +++ b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist @@ -25,7 +25,7 @@ LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSHumanReadableCopyright - Copyright © 2013 Antoine Lagadec. All rights reserved. + Copyright © 2013 Marcus Westin, Antoine Lagadec. All rights reserved. NSMainNibFile MainMenu NSPrincipalClass diff --git a/Example Apps/ExampleApp-OSX/main.m b/Example Apps/ExampleApp-OSX/main.m index ae7b871a..04d99dab 100644 --- a/Example Apps/ExampleApp-OSX/main.m +++ b/Example Apps/ExampleApp-OSX/main.m @@ -1,11 +1,3 @@ -// -// main.m -// ExampleApp-OSX -// -// Created by Antoine Lagadec on 07/04/13. -// Copyright (c) 2013 Antoine Lagadec. All rights reserved. -// - #import int main(int argc, char *argv[]) diff --git a/Example Apps/ExampleApp-iOS/main.m b/Example Apps/ExampleApp-iOS/main.m index a724dc9c..5887dbf1 100644 --- a/Example Apps/ExampleApp-iOS/main.m +++ b/Example Apps/ExampleApp-iOS/main.m @@ -1,11 +1,3 @@ -// -// main.m -// ExampleApp -// -// Created by Marcus Westin on 9/13/12. -// Copyright (c) 2012 Marcus Westin. All rights reserved. -// - #import #import "ExampleAppDelegate.h" diff --git a/LICENSE b/LICENSE index d9d6b12d..1e732703 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011 Marcus Westin +Copyright (c) 2011-2013 Marcus Westin, Antoine Lagadec Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/README.md b/README.md index 562b9152..ef79353f 100644 --- a/README.md +++ b/README.md @@ -191,8 +191,8 @@ WebViewJavascriptBridge uses `NSJSONSerialization` by default. If you need iOS 4 Contributors ------------ - -- [@marcuswestin](https://github.com/marcuswestin) Marcus Westin +- [@marcuswestin](https://github.com/marcuswestin) Marcus Westin (Author) +- [@oakho](https://github.com/oakho) Antoine Lagadec (OS X version) - [@psineur](https://github.com/psineur) Stepan Generalov - [@sergiocampama](https://github.com/sergiocampama) Sergio Campamá - [@stringbean](https://github.com/stringbean) Michael Stringer diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h index 9a8b2f4f..c9943ffa 100644 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h +++ b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h @@ -1,11 +1,3 @@ -// -// WebViewJavascriptBridge+OSX.h -// ExampleApp-OSX -// -// Created by Antoine Lagadec on 07/04/13. -// Copyright (c) 2013 Antoine Lagadec. All rights reserved. -// - #import #import "WebViewJavascriptBridgeAbstract.h" diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m index 02ee2ed2..efe5f8e2 100644 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m +++ b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m @@ -1,11 +1,3 @@ -// -// WebViewJavascriptBridge+OSX.m -// ExampleApp-OSX -// -// Created by Antoine Lagadec on 07/04/13. -// Copyright (c) 2013 Antoine Lagadec. All rights reserved. -// - #import "WebViewJavascriptBridge_OSX.h" @implementation WebViewJavascriptBridge diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h index 3371f49f..69fb7020 100644 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h +++ b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h @@ -1,11 +1,3 @@ -// -// WebViewJavascriptBridge+iOS.h -// ExampleApp-iOS -// -// Created by Antoine Lagadec on 07/04/13. -// Copyright (c) 2013 Marcus Westin. All rights reserved. -// - #import #import "WebViewJavascriptBridgeAbstract.h" diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m index de493c85..c9c48d24 100644 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m +++ b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m @@ -1,11 +1,3 @@ -// -// WebViewJavascriptBridge+iOS.m -// ExampleApp-iOS -// -// Created by Antoine Lagadec on 07/04/13. -// Copyright (c) 2013 Marcus Westin. All rights reserved. -// - #import "WebViewJavascriptBridge_iOS.h" @implementation WebViewJavascriptBridge From 89d96975a95aa18025e4fc0d218699da8f45346b Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Tue, 23 Apr 2013 18:28:58 -0700 Subject: [PATCH 017/285] v3.0.0 with OSX support --- Changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Changelog b/Changelog index 7733b5ac..e5667d04 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,6 @@ +v3.0.0 ++ OSX Support + v2.1.2 + Copy handler and response blocks From 6276d0d54221b8005ef5deb800cc547a6eadebaa Mon Sep 17 00:00:00 2001 From: Peyton Randolph Date: Thu, 6 Jun 2013 14:02:35 -0400 Subject: [PATCH 018/285] add instancetype to class constructors --- WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h | 4 ++-- WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h index 69fb7020..4f606dcb 100644 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h +++ b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h @@ -6,7 +6,7 @@ @property (nonatomic, strong) UIWebView *webView; @property (nonatomic, strong) id webViewDelegate; -+ (id)bridgeForWebView:(UIWebView*)webView handler:(WVJBHandler)handler; -+ (id)bridgeForWebView:(UIWebView*)webView webViewDelegate:(id )webViewDelegate handler:(WVJBHandler)handler; ++ (instancetype)bridgeForWebView:(UIWebView*)webView handler:(WVJBHandler)handler; ++ (instancetype)bridgeForWebView:(UIWebView*)webView webViewDelegate:(id )webViewDelegate handler:(WVJBHandler)handler; @end diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m index c9c48d24..bba73560 100644 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m +++ b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m @@ -4,11 +4,11 @@ @implementation WebViewJavascriptBridge #pragma mark UIWebViewDelegate -+ (id)bridgeForWebView:(UIWebView *)webView handler:(WVJBHandler)handler { ++ (instancetype)bridgeForWebView:(UIWebView *)webView handler:(WVJBHandler)handler { return [self bridgeForWebView:webView webViewDelegate:nil handler:handler]; } -+ (id)bridgeForWebView:(UIWebView *)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { ++ (instancetype)bridgeForWebView:(UIWebView *)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; bridge.messageHandler = messageHandler; bridge.webView = webView; From b06988f14aa92911d9773ef66d53b9822b05f6da Mon Sep 17 00:00:00 2001 From: Peyton Randolph Date: Thu, 6 Jun 2013 14:12:39 -0400 Subject: [PATCH 019/285] fix retain cycle --- .../WebViewJavascriptBridgeAbstract.h | 4 ++-- .../WebViewJavascriptBridgeAbstract.m | 12 ++++++---- .../WebViewJavascriptBridge_iOS.h | 4 ++-- .../WebViewJavascriptBridge_iOS.m | 24 +++++++++++-------- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h index a5d3cd83..a99690f4 100644 --- a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h +++ b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h @@ -7,8 +7,8 @@ typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); @interface WebViewJavascriptBridgeAbstract : NSObject -@property (nonatomic, strong) id webView; -@property (nonatomic, strong) id webViewDelegate; +@property (nonatomic, weak) id webView; +@property (nonatomic, weak) id webViewDelegate; @property (nonatomic, strong) NSMutableArray *startupMessageQueue; @property (nonatomic, strong) NSMutableDictionary *responseCallbacks; @property (nonatomic, strong) NSMutableDictionary *messageHandlers; diff --git a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m index 7e2408a2..0734e6e7 100755 --- a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m +++ b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m @@ -79,13 +79,14 @@ - (void)_dispatchMessage:(NSDictionary *)message { messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]; messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r" withString:@"\\r"]; messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\f" withString:@"\\f"]; + __strong typeof(self.webView) strongWebView = self.webView; if ([[NSThread currentThread] isMainThread]) { - [self.webView performSelector:@selector(stringByEvaluatingJavaScriptFromString:) + [strongWebView performSelector:@selector(stringByEvaluatingJavaScriptFromString:) withObject:[NSString stringWithFormat: @"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]]; } else { dispatch_sync(dispatch_get_main_queue(), ^{ - [self.webView performSelector:@selector(stringByEvaluatingJavaScriptFromString:) + [strongWebView performSelector:@selector(stringByEvaluatingJavaScriptFromString:) withObject:[NSString stringWithFormat: @"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]]; }); @@ -93,7 +94,8 @@ - (void)_dispatchMessage:(NSDictionary *)message { } - (void)_flushMessageQueue { - NSString *messageQueueString = [self.webView performSelector: + __strong typeof(self.webView) strongWebView = self.webView; + NSString *messageQueueString = [strongWebView performSelector: @selector(stringByEvaluatingJavaScriptFromString:) withObject:@"WebViewJavascriptBridge._fetchQueue();"]; NSArray* messages = [messageQueueString componentsSeparatedByString:kMessageSeparator]; @@ -112,8 +114,8 @@ - (void)_flushMessageQueue { __block NSString* callbackId = message[@"callbackId"]; if (callbackId) { responseCallback = ^(id responseData) { - NSDictionary* message = @{ @"responseId":callbackId, @"responseData":responseData }; - [self _queueMessage:message]; + NSDictionary* msg = @{ @"responseId":callbackId, @"responseData":responseData }; + [self _queueMessage:msg]; }; } else { responseCallback = ^(id ignoreResponseData) { diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h index 69fb7020..22752949 100644 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h +++ b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h @@ -3,8 +3,8 @@ @interface WebViewJavascriptBridge : WebViewJavascriptBridgeAbstract -@property (nonatomic, strong) UIWebView *webView; -@property (nonatomic, strong) id webViewDelegate; +@property (nonatomic, weak) UIWebView *webView; +@property (nonatomic, weak) id webViewDelegate; + (id)bridgeForWebView:(UIWebView*)webView handler:(WVJBHandler)handler; + (id)bridgeForWebView:(UIWebView*)webView webViewDelegate:(id )webViewDelegate handler:(WVJBHandler)handler; diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m index c9c48d24..a0275c67 100644 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m +++ b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m @@ -24,10 +24,10 @@ + (id)bridgeForWebView:(UIWebView *)webView webViewDelegate:(id Date: Thu, 6 Jun 2013 14:53:50 -0400 Subject: [PATCH 020/285] track number of resources left to load, fixing race condition --- .../WebViewJavascriptBridge_iOS.m | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m index c9c48d24..739bb0ce 100644 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m +++ b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m @@ -1,5 +1,11 @@ #import "WebViewJavascriptBridge_iOS.h" +@interface WebViewJavascriptBridge () + +@property (nonatomic, assign) NSUInteger numRequestsLoading; + +@end + @implementation WebViewJavascriptBridge #pragma mark UIWebViewDelegate @@ -9,7 +15,7 @@ + (id)bridgeForWebView:(UIWebView *)webView handler:(WVJBHandler)handler { } + (id)bridgeForWebView:(UIWebView *)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { - WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; + WebViewJavascriptBridge* bridge = [[[self class] alloc] init]; bridge.messageHandler = messageHandler; bridge.webView = webView; bridge.webViewDelegate = webViewDelegate; @@ -18,13 +24,16 @@ + (id)bridgeForWebView:(UIWebView *)webView webViewDelegate:(id Date: Thu, 6 Jun 2013 15:00:18 -0400 Subject: [PATCH 021/285] add OS X support --- .../WebViewJavascriptBridge_OSX.m | 18 ++++++++++++++++-- .../WebViewJavascriptBridge_iOS.m | 5 ++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m index efe5f8e2..8c0369b0 100644 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m +++ b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m @@ -1,5 +1,11 @@ #import "WebViewJavascriptBridge_OSX.h" +@interface WebViewJavascriptBridge () + +@property (nonatomic, assign) NSUInteger numRequestsLoading; + +@end + @implementation WebViewJavascriptBridge + (id)bridgeForWebView:(WebView *)webView handler:(WVJBHandler)handler { @@ -17,7 +23,7 @@ + (id)bridgeForWebView:(WebView *)webView webViewDelegate:(id)webViewDelegate ha bridge.webView.frameLoadDelegate = bridge; bridge.webView.resourceLoadDelegate = bridge; bridge.webView.policyDelegate = bridge; - + return bridge; } @@ -25,7 +31,9 @@ - (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame { if (webView != self.webView) { return; } - if (![[self.webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { + self.numRequestsLoading--; + + if (self.numRequestsLoading == 0 && ![[self.webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; [self.webView stringByEvaluatingJavaScriptFromString:js]; @@ -45,6 +53,9 @@ - (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame - (void)webView:(WebView *)webView didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { if (webView != self.webView) { return; } + + self.numRequestsLoading--; + if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) { [self.webViewDelegate webView:self.webView didFailLoadWithError:error forFrame:frame]; } @@ -78,6 +89,9 @@ - (void)webView:(WebView *)webView didCommitLoadForFrame:(WebFrame *)frame { - (NSURLRequest *)webView:(WebView *)webView resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource { if (webView != self.webView) { return request; } + + self.numRequestsLoading++; + if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) { return [self.webViewDelegate webView:webView resource:identifier willSendRequest:request redirectResponse:redirectResponse fromDataSource:dataSource]; } diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m index 739bb0ce..0dbe4265 100644 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m +++ b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m @@ -23,14 +23,13 @@ + (id)bridgeForWebView:(UIWebView *)webView webViewDelegate:(id Date: Thu, 6 Jun 2013 15:01:10 -0400 Subject: [PATCH 022/285] add OS X support --- WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h | 4 ++-- WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h index c9943ffa..af46430d 100644 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h +++ b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h @@ -6,7 +6,7 @@ @property (nonatomic, strong) WebView *webView; @property (nonatomic, strong) id webViewDelegate; -+ (id)bridgeForWebView:(WebView*)webView handler:(WVJBHandler)handler; -+ (id)bridgeForWebView:(WebView*)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)handler; ++ (instancetype)bridgeForWebView:(WebView*)webView handler:(WVJBHandler)handler; ++ (instancetype)bridgeForWebView:(WebView*)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)handler; @end diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m index efe5f8e2..9efed22c 100644 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m +++ b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m @@ -2,11 +2,11 @@ @implementation WebViewJavascriptBridge -+ (id)bridgeForWebView:(WebView *)webView handler:(WVJBHandler)handler { ++ (instancetype)bridgeForWebView:(WebView *)webView handler:(WVJBHandler)handler { return [self bridgeForWebView:webView webViewDelegate:nil handler:handler]; } -+ (id)bridgeForWebView:(WebView *)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { ++ (instancetype)bridgeForWebView:(WebView *)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; bridge.messageHandler = messageHandler; bridge.webView = webView; From 5ec6c29ca01c04cad7037365d596742367dd7e39 Mon Sep 17 00:00:00 2001 From: Peyton Randolph Date: Thu, 6 Jun 2013 15:06:41 -0400 Subject: [PATCH 023/285] add OS X support --- .../WebViewJavascriptBridge_OSX.h | 4 +-- .../WebViewJavascriptBridge_OSX.m | 33 +++++++++++-------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h index c9943ffa..89a89ab4 100644 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h +++ b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h @@ -3,8 +3,8 @@ @interface WebViewJavascriptBridge : WebViewJavascriptBridgeAbstract -@property (nonatomic, strong) WebView *webView; -@property (nonatomic, strong) id webViewDelegate; +@property (nonatomic, weak) WebView *webView; +@property (nonatomic, weak) id webViewDelegate; + (id)bridgeForWebView:(WebView*)webView handler:(WVJBHandler)handler; + (id)bridgeForWebView:(WebView*)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)handler; diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m index efe5f8e2..b90ff37c 100644 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m +++ b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m @@ -7,7 +7,7 @@ + (id)bridgeForWebView:(WebView *)webView handler:(WVJBHandler)handler { } + (id)bridgeForWebView:(WebView *)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { - WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; + WebViewJavascriptBridge* bridge = [[[self class] alloc] init]; bridge.messageHandler = messageHandler; bridge.webView = webView; bridge.webViewDelegate = webViewDelegate; @@ -25,10 +25,10 @@ - (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame { if (webView != self.webView) { return; } - if (![[self.webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { + if (![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; - [self.webView stringByEvaluatingJavaScriptFromString:js]; + [webView stringByEvaluatingJavaScriptFromString:js]; } if (self.startupMessageQueue) { @@ -38,15 +38,17 @@ - (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame self.startupMessageQueue = nil; } - if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)]) { - [self.webViewDelegate webView:webView didFinishLoadForFrame:frame]; + __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)]) { + [strongDelegate webView:webView didFinishLoadForFrame:frame]; } } - (void)webView:(WebView *)webView didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { if (webView != self.webView) { return; } - if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) { - [self.webViewDelegate webView:self.webView didFailLoadWithError:error forFrame:frame]; + __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) { + [strongDelegate webView:strongDelegate didFailLoadWithError:error forFrame:frame]; } } @@ -54,6 +56,7 @@ - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary { if (webView != self.webView) { [listener use]; } NSURL *url = [request URL]; + __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; if ([[url scheme] isEqualToString:kCustomProtocolScheme]) { if ([[url host] isEqualToString:kQueueHasMessage]) { [self _flushMessageQueue]; @@ -61,9 +64,9 @@ - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", kCustomProtocolScheme, [url path]); } [listener ignore]; - } else if ([self.webView resourceLoadDelegate] - && [self.webViewDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:request:frame:decisionListener:)]) { - [self.webViewDelegate webView:webView decidePolicyForNavigationAction:actionInformation request:request frame:frame decisionListener:listener]; + } else if ([webView resourceLoadDelegate] + && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:request:frame:decisionListener:)]) { + [strongDelegate webView:webView decidePolicyForNavigationAction:actionInformation request:request frame:frame decisionListener:listener]; } else { [listener use]; } @@ -71,15 +74,17 @@ - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary - (void)webView:(WebView *)webView didCommitLoadForFrame:(WebFrame *)frame { if (webView != self.webView) { return; } - if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:didCommitLoadForFrame:)]) { - [self.webViewDelegate webView:webView didCommitLoadForFrame:frame]; + __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didCommitLoadForFrame:)]) { + [strongDelegate webView:webView didCommitLoadForFrame:frame]; } } - (NSURLRequest *)webView:(WebView *)webView resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource { if (webView != self.webView) { return request; } - if (self.webViewDelegate && [self.webViewDelegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) { - return [self.webViewDelegate webView:webView resource:identifier willSendRequest:request redirectResponse:redirectResponse fromDataSource:dataSource]; + __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) { + return [strongDelegate webView:webView resource:identifier willSendRequest:request redirectResponse:redirectResponse fromDataSource:dataSource]; } return request; From 618fe2ed74c92d8480c5ef9857a7901f4fea104e Mon Sep 17 00:00:00 2001 From: Peyton Randolph Date: Thu, 6 Jun 2013 15:12:10 -0400 Subject: [PATCH 024/285] add weak fallback for iOS 4 --- .../WebViewJavascriptBridgeAbstract.h | 12 ++++++++++-- .../WebViewJavascriptBridge_OSX.h | 4 ++-- .../WebViewJavascriptBridge_iOS.h | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h index a99690f4..de80ba9d 100644 --- a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h +++ b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h @@ -2,13 +2,21 @@ #define kCustomProtocolScheme @"wvjbscheme" #define kQueueHasMessage @"__WVJB_QUEUE_MESSAGE__" +#if TARGET_OS_IPHONE && defined(__IPHONE_5_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0) + #define WEAK_FALLBACK weak +#elif TARGET_OS_MAC && defined(__MAC_10_7) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_7) + #define WEAK_FALLBACK weak +#else + #define WEAK_FALLBACK unsafe_unretained +#endif + typedef void (^WVJBResponseCallback)(id responseData); typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); @interface WebViewJavascriptBridgeAbstract : NSObject -@property (nonatomic, weak) id webView; -@property (nonatomic, weak) id webViewDelegate; +@property (nonatomic, WEAK_FALLBACK) id webView; +@property (nonatomic, WEAK_FALLBACK) id webViewDelegate; @property (nonatomic, strong) NSMutableArray *startupMessageQueue; @property (nonatomic, strong) NSMutableDictionary *responseCallbacks; @property (nonatomic, strong) NSMutableDictionary *messageHandlers; diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h index 89a89ab4..c55bff02 100644 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h +++ b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h @@ -3,8 +3,8 @@ @interface WebViewJavascriptBridge : WebViewJavascriptBridgeAbstract -@property (nonatomic, weak) WebView *webView; -@property (nonatomic, weak) id webViewDelegate; +@property (nonatomic, WEAK_FALLBACK) WebView *webView; +@property (nonatomic, WEAK_FALLBACK) id webViewDelegate; + (id)bridgeForWebView:(WebView*)webView handler:(WVJBHandler)handler; + (id)bridgeForWebView:(WebView*)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)handler; diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h index 22752949..f1b318a5 100644 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h +++ b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h @@ -3,8 +3,8 @@ @interface WebViewJavascriptBridge : WebViewJavascriptBridgeAbstract -@property (nonatomic, weak) UIWebView *webView; -@property (nonatomic, weak) id webViewDelegate; +@property (nonatomic, WEAK_FALLBACK) UIWebView *webView; +@property (nonatomic, WEAK_FALLBACK) id webViewDelegate; + (id)bridgeForWebView:(UIWebView*)webView handler:(WVJBHandler)handler; + (id)bridgeForWebView:(UIWebView*)webView webViewDelegate:(id )webViewDelegate handler:(WVJBHandler)handler; From 20ce1b0bcff3caa6e71b024647121498b82517dc Mon Sep 17 00:00:00 2001 From: Peyton Randolph Date: Thu, 6 Jun 2013 15:17:27 -0400 Subject: [PATCH 025/285] nil out delegates on dealloc --- WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m | 7 +++++++ WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m index b90ff37c..9259e48d 100644 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m +++ b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m @@ -21,6 +21,13 @@ + (id)bridgeForWebView:(WebView *)webView webViewDelegate:(id)webViewDelegate ha return bridge; } +- (void)dealloc; +{ + self.webView.frameLoadDelegate = nil; + self.webView.resourceLoadDelegate = nil; + self.webView.policyDelegate = nil; +} + - (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame { if (webView != self.webView) { return; } diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m index a0275c67..d05b670c 100644 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m +++ b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m @@ -21,6 +21,11 @@ + (id)bridgeForWebView:(UIWebView *)webView webViewDelegate:(id Date: Thu, 6 Jun 2013 12:35:56 -0700 Subject: [PATCH 026/285] Add @peyton to list of contributors --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ef79353f..e9bf51d4 100644 --- a/README.md +++ b/README.md @@ -201,3 +201,4 @@ Contributors - [@pj4533](https://github.com/pj4533) PJ Gray - [@xzeror](https://github.com/xzeror) - [@kelp404](https://github.com/kelp404) +- [@peyton](https://github.com/peyton) Peyton Randolph From 818d49cfc3bece2feee2a9c652520ad3f499e91e Mon Sep 17 00:00:00 2001 From: Peyton Randolph Date: Thu, 6 Jun 2013 16:04:40 -0400 Subject: [PATCH 027/285] Add podspec --- WebViewJavascriptBridge.podspec | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 WebViewJavascriptBridge.podspec diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec new file mode 100644 index 00000000..79735999 --- /dev/null +++ b/WebViewJavascriptBridge.podspec @@ -0,0 +1,16 @@ +Pod::Spec.new do |s| + s.name = 'WebViewJavascriptBridge' + s.version = '4.0.0pre' + s.summary = 'An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews.' + s.homepage = 'http://github.com/marcuswestin/WebViewJavascriptBridge' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'marcuswestin' => 'marcus.westin@gmail.com' } + s.source = { :git => 'https://github.com/peyton/WebViewJavascriptBridge.git' } + s.ios.platform = :ios, '5.0' + s.osx.platform = :osx + s.ios.source_files = 'WebViewJavascriptBridge_iOS/*.{h,m}', 'WebViewJavascriptBridgeAbstract/*.{h,m}' + s.osx.source_files = 'WebViewJavascriptBridge_OSX/*.{h,m}', 'WebViewJavascriptBridgeAbstract/*.{h,m}' + s.resource = 'WebViewJavascriptBridgeAbstract/WebViewJavascriptBridge.js.txt' + s.ios.framework = 'UIKit' + s.osx.framework = 'WebKit' +end From 7f0ec42415e513ea679c467ceb2f41a952aeb0bb Mon Sep 17 00:00:00 2001 From: Peyton Randolph Date: Thu, 6 Jun 2013 16:12:11 -0400 Subject: [PATCH 028/285] fix bug --- WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m | 1 - 1 file changed, 1 deletion(-) diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m index fce01d8f..59311ffe 100644 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m +++ b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m @@ -38,7 +38,6 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView { self.numRequestsLoading--; if (self.numRequestsLoading == 0 && ![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { - if (![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; [webView stringByEvaluatingJavaScriptFromString:js]; From 95afe41a2cfa5232e61f58dc6a1d932a2274a6e3 Mon Sep 17 00:00:00 2001 From: Peyton Randolph Date: Thu, 6 Jun 2013 16:17:39 -0400 Subject: [PATCH 029/285] add requires_arc --- WebViewJavascriptBridge.podspec | 1 + 1 file changed, 1 insertion(+) diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index 79735999..3a2c63cd 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -5,6 +5,7 @@ Pod::Spec.new do |s| s.homepage = 'http://github.com/marcuswestin/WebViewJavascriptBridge' s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { 'marcuswestin' => 'marcus.westin@gmail.com' } + s.requires_arc = true s.source = { :git => 'https://github.com/peyton/WebViewJavascriptBridge.git' } s.ios.platform = :ios, '5.0' s.osx.platform = :osx From 4f58e829160543f2adca4e483acf99596e7b70ba Mon Sep 17 00:00:00 2001 From: Peyton Randolph Date: Fri, 7 Jun 2013 07:44:51 -0400 Subject: [PATCH 030/285] point podspec to the parent repo --- WebViewJavascriptBridge.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index 3a2c63cd..76b49fbd 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -6,7 +6,7 @@ Pod::Spec.new do |s| s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { 'marcuswestin' => 'marcus.westin@gmail.com' } s.requires_arc = true - s.source = { :git => 'https://github.com/peyton/WebViewJavascriptBridge.git' } + s.source = { :git => 'https://github.com/marcuswestin/WebViewJavascriptBridge.git' } s.ios.platform = :ios, '5.0' s.osx.platform = :osx s.ios.source_files = 'WebViewJavascriptBridge_iOS/*.{h,m}', 'WebViewJavascriptBridgeAbstract/*.{h,m}' From 8f1aaf9b3743d37df178e503f708b9cae3892c0c Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Sat, 8 Jun 2013 01:12:38 -0700 Subject: [PATCH 031/285] Fix #41 - remove __block to avoid losing callbackId. See http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/Blocks/Articles/bxVariables.html "Types of variables" #3 and #4 - we want callbackId to be non-mutable, const --- .../WebViewJavascriptBridgeAbstract.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m index 0734e6e7..98218c31 100755 --- a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m +++ b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m @@ -111,7 +111,7 @@ - (void)_flushMessageQueue { [self.responseCallbacks removeObjectForKey:responseId]; } else { WVJBResponseCallback responseCallback = NULL; - __block NSString* callbackId = message[@"callbackId"]; + NSString* callbackId = message[@"callbackId"]; if (callbackId) { responseCallback = ^(id responseData) { NSDictionary* msg = @{ @"responseId":callbackId, @"responseData":responseData }; From 2f1623a2642c08ef2b95c7e4f06cab94a924d73b Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Sat, 8 Jun 2013 01:18:57 -0700 Subject: [PATCH 032/285] v3.1.0 --- Changelog | 7 +++++++ WebViewJavascriptBridge.podspec | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index e5667d04..849cadb2 100644 --- a/Changelog +++ b/Changelog @@ -1,5 +1,12 @@ +v3.1.0 ++ Dont inject the WVJB bridge until all requests have finished loading (61b853) ++ Add podspec file (818d49cfc) ++ Memory leaks fixed (b06988f1, 20ce1b0b) ++ New major contributor @peyton! + v3.0.0 + OSX Support ++ New major contributor @oakho! v2.1.2 + Copy handler and response blocks diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index 76b49fbd..647d8328 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'WebViewJavascriptBridge' - s.version = '4.0.0pre' + s.version = '3.1.0' s.summary = 'An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews.' s.homepage = 'http://github.com/marcuswestin/WebViewJavascriptBridge' s.license = { :type => 'MIT', :file => 'LICENSE' } From 9e6972834d0e6f937086827d6cb3cf963f55aff0 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Sat, 8 Jun 2013 19:54:47 -0700 Subject: [PATCH 033/285] Remove the current OS X based example app, to be replaced in the next commit by a strictly programmatically created app --- .../ExampleApp-OSX.xcodeproj/project.pbxproj | 334 -- Example Apps/ExampleApp-OSX/AppDelegate.h | 14 - Example Apps/ExampleApp-OSX/AppDelegate.m | 51 - .../ExampleApp-OSX/ExampleApp-OSX-Info.plist | 34 - .../ExampleApp-OSX/ExampleApp-OSX-Prefix.pch | 7 - .../ExampleApp-OSX/en.lproj/InfoPlist.strings | 2 - .../ExampleApp-OSX/en.lproj/MainMenu.xib | 3614 ----------------- Example Apps/ExampleApp-OSX/main.m | 6 - 8 files changed, 4062 deletions(-) delete mode 100644 Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj delete mode 100644 Example Apps/ExampleApp-OSX/AppDelegate.h delete mode 100644 Example Apps/ExampleApp-OSX/AppDelegate.m delete mode 100644 Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist delete mode 100644 Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch delete mode 100644 Example Apps/ExampleApp-OSX/en.lproj/InfoPlist.strings delete mode 100644 Example Apps/ExampleApp-OSX/en.lproj/MainMenu.xib delete mode 100644 Example Apps/ExampleApp-OSX/main.m diff --git a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj deleted file mode 100644 index 5e5e13ab..00000000 --- a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj +++ /dev/null @@ -1,334 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 2CA045DA171178E5006DEE8B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CA045D9171178E5006DEE8B /* Cocoa.framework */; }; - 2CA045E4171178E6006DEE8B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045E2171178E6006DEE8B /* InfoPlist.strings */; }; - 2CA045E6171178E6006DEE8B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045E5171178E6006DEE8B /* main.m */; }; - 2CA045ED171178E6006DEE8B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045EC171178E6006DEE8B /* AppDelegate.m */; }; - 2CA045F0171178E6006DEE8B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045EE171178E6006DEE8B /* MainMenu.xib */; }; - 2CA0460517117B56006DEE8B /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CA0460417117B56006DEE8B /* WebKit.framework */; }; - 2CA0465E1711AC96006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA0465D1711AC96006DEE8B /* ExampleApp.html */; }; - 2CAB8695172766DF00BD9ED1 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CAB8690172766DF00BD9ED1 /* WebViewJavascriptBridge.js.txt */; }; - 2CAB8696172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CAB8692172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.m */; }; - 2CAB8697172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CAB8694172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 2CA045D5171178E5006DEE8B /* ExampleApp-OSX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ExampleApp-OSX.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 2CA045D9171178E5006DEE8B /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; - 2CA045DC171178E5006DEE8B /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; - 2CA045DD171178E5006DEE8B /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; - 2CA045DE171178E5006DEE8B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 2CA045E1171178E6006DEE8B /* ExampleApp-OSX-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ExampleApp-OSX-Info.plist"; sourceTree = ""; }; - 2CA045E3171178E6006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - 2CA045E5171178E6006DEE8B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 2CA045E7171178E6006DEE8B /* ExampleApp-OSX-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ExampleApp-OSX-Prefix.pch"; sourceTree = ""; }; - 2CA045EB171178E6006DEE8B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 2CA045EC171178E6006DEE8B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 2CA045EF171178E6006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; - 2CA0460417117B56006DEE8B /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; - 2CA0465D1711AC96006DEE8B /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = ExampleApp.html; path = ../ExampleApp.html; sourceTree = ""; }; - 2CAB8690172766DF00BD9ED1 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; - 2CAB8691172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; - 2CAB8692172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; - 2CAB8693172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_OSX.h; sourceTree = ""; }; - 2CAB8694172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_OSX.m; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 2CA045D2171178E5006DEE8B /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 2CA0460517117B56006DEE8B /* WebKit.framework in Frameworks */, - 2CA045DA171178E5006DEE8B /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 2CA045CA171178E5006DEE8B = { - isa = PBXGroup; - children = ( - 2CA0460417117B56006DEE8B /* WebKit.framework */, - 2CA045DF171178E5006DEE8B /* ExampleApp-OSX */, - 2CA045D8171178E5006DEE8B /* Frameworks */, - 2CA045D6171178E5006DEE8B /* Products */, - ); - sourceTree = ""; - }; - 2CA045D6171178E5006DEE8B /* Products */ = { - isa = PBXGroup; - children = ( - 2CA045D5171178E5006DEE8B /* ExampleApp-OSX.app */, - ); - name = Products; - sourceTree = ""; - }; - 2CA045D8171178E5006DEE8B /* Frameworks */ = { - isa = PBXGroup; - children = ( - 2CA045D9171178E5006DEE8B /* Cocoa.framework */, - 2CA045DB171178E5006DEE8B /* Other Frameworks */, - ); - name = Frameworks; - sourceTree = ""; - }; - 2CA045DB171178E5006DEE8B /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - 2CA045DC171178E5006DEE8B /* AppKit.framework */, - 2CA045DD171178E5006DEE8B /* CoreData.framework */, - 2CA045DE171178E5006DEE8B /* Foundation.framework */, - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - 2CA045DF171178E5006DEE8B /* ExampleApp-OSX */ = { - isa = PBXGroup; - children = ( - 2CA0465D1711AC96006DEE8B /* ExampleApp.html */, - 2CA045EB171178E6006DEE8B /* AppDelegate.h */, - 2CA045EC171178E6006DEE8B /* AppDelegate.m */, - 2CA045EE171178E6006DEE8B /* MainMenu.xib */, - 2CAB868E172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX */, - 2CA045E0171178E6006DEE8B /* Supporting Files */, - ); - path = "ExampleApp-OSX"; - sourceTree = ""; - }; - 2CA045E0171178E6006DEE8B /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 2CA045E1171178E6006DEE8B /* ExampleApp-OSX-Info.plist */, - 2CA045E2171178E6006DEE8B /* InfoPlist.strings */, - 2CA045E5171178E6006DEE8B /* main.m */, - 2CA045E7171178E6006DEE8B /* ExampleApp-OSX-Prefix.pch */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 2CAB868E172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX */ = { - isa = PBXGroup; - children = ( - 2CAB868F172766DF00BD9ED1 /* WebViewJavascriptAbstract */, - 2CAB8693172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.h */, - 2CAB8694172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.m */, - ); - name = WebViewJavascriptBridge_OSX; - path = ../../WebViewJavascriptBridge_OSX; - sourceTree = ""; - }; - 2CAB868F172766DF00BD9ED1 /* WebViewJavascriptAbstract */ = { - isa = PBXGroup; - children = ( - 2CAB8690172766DF00BD9ED1 /* WebViewJavascriptBridge.js.txt */, - 2CAB8691172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.h */, - 2CAB8692172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.m */, - ); - path = WebViewJavascriptAbstract; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 2CA045D4171178E5006DEE8B /* ExampleApp-OSX */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2CA045F3171178E6006DEE8B /* Build configuration list for PBXNativeTarget "ExampleApp-OSX" */; - buildPhases = ( - 2CA045D1171178E5006DEE8B /* Sources */, - 2CA045D2171178E5006DEE8B /* Frameworks */, - 2CA045D3171178E5006DEE8B /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "ExampleApp-OSX"; - productName = "ExampleApp-OSX"; - productReference = 2CA045D5171178E5006DEE8B /* ExampleApp-OSX.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 2CA045CC171178E5006DEE8B /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0450; - ORGANIZATIONNAME = "Antoine Lagadec"; - }; - buildConfigurationList = 2CA045CF171178E5006DEE8B /* Build configuration list for PBXProject "ExampleApp-OSX" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 2CA045CA171178E5006DEE8B; - productRefGroup = 2CA045D6171178E5006DEE8B /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 2CA045D4171178E5006DEE8B /* ExampleApp-OSX */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 2CA045D3171178E5006DEE8B /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2CA045E4171178E6006DEE8B /* InfoPlist.strings in Resources */, - 2CA045F0171178E6006DEE8B /* MainMenu.xib in Resources */, - 2CA0465E1711AC96006DEE8B /* ExampleApp.html in Resources */, - 2CAB8695172766DF00BD9ED1 /* WebViewJavascriptBridge.js.txt in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 2CA045D1171178E5006DEE8B /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2CA045E6171178E6006DEE8B /* main.m in Sources */, - 2CA045ED171178E6006DEE8B /* AppDelegate.m in Sources */, - 2CAB8696172766DF00BD9ED1 /* WebViewJavascriptBridgeAbstract.m in Sources */, - 2CAB8697172766DF00BD9ED1 /* WebViewJavascriptBridge_OSX.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 2CA045E2171178E6006DEE8B /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 2CA045E3171178E6006DEE8B /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - 2CA045EE171178E6006DEE8B /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - 2CA045EF171178E6006DEE8B /* en */, - ); - name = MainMenu.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 2CA045F1171178E6006DEE8B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.7; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - }; - name = Debug; - }; - 2CA045F2171178E6006DEE8B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.7; - SDKROOT = macosx; - }; - name = Release; - }; - 2CA045F4171178E6006DEE8B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "ExampleApp-OSX/ExampleApp-OSX-Prefix.pch"; - INFOPLIST_FILE = "ExampleApp-OSX/ExampleApp-OSX-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - 2CA045F5171178E6006DEE8B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "ExampleApp-OSX/ExampleApp-OSX-Prefix.pch"; - INFOPLIST_FILE = "ExampleApp-OSX/ExampleApp-OSX-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 2CA045CF171178E5006DEE8B /* Build configuration list for PBXProject "ExampleApp-OSX" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2CA045F1171178E6006DEE8B /* Debug */, - 2CA045F2171178E6006DEE8B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 2CA045F3171178E6006DEE8B /* Build configuration list for PBXNativeTarget "ExampleApp-OSX" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2CA045F4171178E6006DEE8B /* Debug */, - 2CA045F5171178E6006DEE8B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 2CA045CC171178E5006DEE8B /* Project object */; -} diff --git a/Example Apps/ExampleApp-OSX/AppDelegate.h b/Example Apps/ExampleApp-OSX/AppDelegate.h deleted file mode 100644 index ddbd75fd..00000000 --- a/Example Apps/ExampleApp-OSX/AppDelegate.h +++ /dev/null @@ -1,14 +0,0 @@ -#import -#import "WebViewJavascriptBridge_OSX.h" - -@interface AppDelegate : NSObject - -@property (assign) IBOutlet NSWindow *window; -@property (weak) IBOutlet WebView *webView; - -- (IBAction)sendMessage:(id)sender; -- (IBAction)callHandler:(id)sender; - -@property (strong, nonatomic) WebViewJavascriptBridge *javascriptBridge; - -@end diff --git a/Example Apps/ExampleApp-OSX/AppDelegate.m b/Example Apps/ExampleApp-OSX/AppDelegate.m deleted file mode 100644 index 4db9997b..00000000 --- a/Example Apps/ExampleApp-OSX/AppDelegate.m +++ /dev/null @@ -1,51 +0,0 @@ -#import "AppDelegate.h" - -@implementation AppDelegate - -@synthesize javascriptBridge = _bridge; - -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification -{ - [WebViewJavascriptBridge enableLogging]; - - _bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView handler:^(id data, WVJBResponseCallback responseCallback) { - NSLog(@"ObjC received message from JS: %@", data); - responseCallback(@"Response for message from ObjC"); - }]; - - [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { - NSLog(@"testObjcCallback called: %@", data); - responseCallback(@"Response from testObjcCallback"); - }]; - - [_bridge send:@"A string sent from ObjC before Webview has loaded." responseCallback:^(id responseData) { - NSLog(@"objc got response! %@", responseData); - }]; - - [_bridge callHandler:@"testJavascriptHandler" data:[NSDictionary dictionaryWithObject:@"before ready" forKey:@"foo"]]; - - [self loadExamplePage:self.webView]; - - [_bridge send:@"A string sent from ObjC after Webview has loaded."]; -} - -- (IBAction)sendMessage:(id)sender { - [_bridge send:@"A string sent from ObjC to JS" responseCallback:^(id response) { - NSLog(@"sendMessage got response: %@", response); - }]; -} - -- (IBAction)callHandler:(id)sender { - NSDictionary* data = [NSDictionary dictionaryWithObject:@"Hi there, JS!" forKey:@"greetingFromObjC"]; - [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { - NSLog(@"testJavascriptHandler responded: %@", response); - }]; -} - -- (void)loadExamplePage:(WebView*)webView { - NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; - NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; - [[self.webView mainFrame] loadHTMLString:appHtml baseURL:nil]; -} - -@end diff --git a/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist deleted file mode 100644 index 18703404..00000000 --- a/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist +++ /dev/null @@ -1,34 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - - CFBundleIdentifier - example.${PRODUCT_NAME:rfc1034identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSMinimumSystemVersion - ${MACOSX_DEPLOYMENT_TARGET} - NSHumanReadableCopyright - Copyright © 2013 Marcus Westin, Antoine Lagadec. All rights reserved. - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - - diff --git a/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch deleted file mode 100644 index 32daebd5..00000000 --- a/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'ExampleApp-OSX' target in the 'ExampleApp-OSX' project -// - -#ifdef __OBJC__ - #import -#endif diff --git a/Example Apps/ExampleApp-OSX/en.lproj/InfoPlist.strings b/Example Apps/ExampleApp-OSX/en.lproj/InfoPlist.strings deleted file mode 100644 index 477b28ff..00000000 --- a/Example Apps/ExampleApp-OSX/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/Example Apps/ExampleApp-OSX/en.lproj/MainMenu.xib b/Example Apps/ExampleApp-OSX/en.lproj/MainMenu.xib deleted file mode 100644 index b4989b1d..00000000 --- a/Example Apps/ExampleApp-OSX/en.lproj/MainMenu.xib +++ /dev/null @@ -1,3614 +0,0 @@ - - - - 1070 - 11E53 - 2844 - 1138.47 - 569.00 - - 2844 - 1810 - - - IBNSLayoutConstraint - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSView - NSWindowTemplate - WebView - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - - - PluginDependencyRecalculationVersion - - - - - NSApplication - - - FirstResponder - - - NSApplication - - - AMainMenu - - - - ExampleApp-OSX - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - ExampleApp-OSX - - - - About ExampleApp-OSX - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Preferences… - , - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Services - - 1048576 - 2147483647 - - - submenuAction: - - Services - - _NSServicesMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Hide ExampleApp-OSX - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Quit ExampleApp-OSX - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - File - - 1048576 - 2147483647 - - - submenuAction: - - File - - - - New - n - 1048576 - 2147483647 - - - - - - Open… - o - 1048576 - 2147483647 - - - - - - Open Recent - - 1048576 - 2147483647 - - - submenuAction: - - Open Recent - - - - Clear Menu - - 1048576 - 2147483647 - - - - - _NSRecentDocumentsMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Close - w - 1048576 - 2147483647 - - - - - - Save… - s - 1048576 - 2147483647 - - - - - - Revert to Saved - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Page Setup... - P - 1179648 - 2147483647 - - - - - - - Print… - p - 1048576 - 2147483647 - - - - - - - - - Edit - - 1048576 - 2147483647 - - - submenuAction: - - Edit - - - - Undo - z - 1048576 - 2147483647 - - - - - - Redo - Z - 1179648 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Cut - x - 1048576 - 2147483647 - - - - - - Copy - c - 1048576 - 2147483647 - - - - - - Paste - v - 1048576 - 2147483647 - - - - - - Paste and Match Style - V - 1572864 - 2147483647 - - - - - - Delete - - 1048576 - 2147483647 - - - - - - Select All - a - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Find - - 1048576 - 2147483647 - - - submenuAction: - - Find - - - - Find… - f - 1048576 - 2147483647 - - - 1 - - - - Find and Replace… - f - 1572864 - 2147483647 - - - 12 - - - - Find Next - g - 1048576 - 2147483647 - - - 2 - - - - Find Previous - G - 1179648 - 2147483647 - - - 3 - - - - Use Selection for Find - e - 1048576 - 2147483647 - - - 7 - - - - Jump to Selection - j - 1048576 - 2147483647 - - - - - - - - - Spelling and Grammar - - 1048576 - 2147483647 - - - submenuAction: - - Spelling and Grammar - - - - Show Spelling and Grammar - : - 1048576 - 2147483647 - - - - - - Check Document Now - ; - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Check Spelling While Typing - - 1048576 - 2147483647 - - - - - - Check Grammar With Spelling - - 1048576 - 2147483647 - - - - - - Correct Spelling Automatically - - 2147483647 - - - - - - - - - Substitutions - - 1048576 - 2147483647 - - - submenuAction: - - Substitutions - - - - Show Substitutions - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Smart Copy/Paste - f - 1048576 - 2147483647 - - - 1 - - - - Smart Quotes - g - 1048576 - 2147483647 - - - 2 - - - - Smart Dashes - - 2147483647 - - - - - - Smart Links - G - 1179648 - 2147483647 - - - 3 - - - - Text Replacement - - 2147483647 - - - - - - - - - Transformations - - 2147483647 - - - submenuAction: - - Transformations - - - - Make Upper Case - - 2147483647 - - - - - - Make Lower Case - - 2147483647 - - - - - - Capitalize - - 2147483647 - - - - - - - - - Speech - - 1048576 - 2147483647 - - - submenuAction: - - Speech - - - - Start Speaking - - 1048576 - 2147483647 - - - - - - Stop Speaking - - 1048576 - 2147483647 - - - - - - - - - - - - Format - - 2147483647 - - - submenuAction: - - Format - - - - Font - - 2147483647 - - - submenuAction: - - Font - - - - Show Fonts - t - 1048576 - 2147483647 - - - - - - Bold - b - 1048576 - 2147483647 - - - 2 - - - - Italic - i - 1048576 - 2147483647 - - - 1 - - - - Underline - u - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Bigger - + - 1048576 - 2147483647 - - - 3 - - - - Smaller - - - 1048576 - 2147483647 - - - 4 - - - - YES - YES - - - 2147483647 - - - - - - Kern - - 2147483647 - - - submenuAction: - - Kern - - - - Use Default - - 2147483647 - - - - - - Use None - - 2147483647 - - - - - - Tighten - - 2147483647 - - - - - - Loosen - - 2147483647 - - - - - - - - - Ligatures - - 2147483647 - - - submenuAction: - - Ligatures - - - - Use Default - - 2147483647 - - - - - - Use None - - 2147483647 - - - - - - Use All - - 2147483647 - - - - - - - - - Baseline - - 2147483647 - - - submenuAction: - - Baseline - - - - Use Default - - 2147483647 - - - - - - Superscript - - 2147483647 - - - - - - Subscript - - 2147483647 - - - - - - Raise - - 2147483647 - - - - - - Lower - - 2147483647 - - - - - - - - - YES - YES - - - 2147483647 - - - - - - Show Colors - C - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Copy Style - c - 1572864 - 2147483647 - - - - - - Paste Style - v - 1572864 - 2147483647 - - - - - _NSFontMenu - - - - - Text - - 2147483647 - - - submenuAction: - - Text - - - - Align Left - { - 1048576 - 2147483647 - - - - - - Center - | - 1048576 - 2147483647 - - - - - - Justify - - 2147483647 - - - - - - Align Right - } - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Writing Direction - - 2147483647 - - - submenuAction: - - Writing Direction - - - - YES - Paragraph - - 2147483647 - - - - - - CURlZmF1bHQ - - 2147483647 - - - - - - CUxlZnQgdG8gUmlnaHQ - - 2147483647 - - - - - - CVJpZ2h0IHRvIExlZnQ - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - YES - Selection - - 2147483647 - - - - - - CURlZmF1bHQ - - 2147483647 - - - - - - CUxlZnQgdG8gUmlnaHQ - - 2147483647 - - - - - - CVJpZ2h0IHRvIExlZnQ - - 2147483647 - - - - - - - - - YES - YES - - - 2147483647 - - - - - - Show Ruler - - 2147483647 - - - - - - Copy Ruler - c - 1310720 - 2147483647 - - - - - - Paste Ruler - v - 1310720 - 2147483647 - - - - - - - - - - - - View - - 1048576 - 2147483647 - - - submenuAction: - - View - - - - Show Toolbar - t - 1572864 - 2147483647 - - - - - - Customize Toolbar… - - 1048576 - 2147483647 - - - - - - - - - Window - - 1048576 - 2147483647 - - - submenuAction: - - Window - - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Bring All to Front - - 1048576 - 2147483647 - - - - - _NSWindowsMenu - - - - - Help - - 2147483647 - - - submenuAction: - - Help - - - - ExampleApp-OSX Help - ? - 1048576 - 2147483647 - - - - - _NSHelpMenu - - - - _NSMainMenu - - - 15 - 2 - {{335, 390}, {480, 360}} - 1954021376 - ExampleApp-OSX - NSWindow - - - - - 256 - - - - 256 - - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple URL pasteboard type - Apple Web Archive pasteboard type - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - WebURLsWithTitlesPboardType - public.png - public.url - public.url-name - - {{0, 37}, {480, 323}} - - - - _NS:9 - - - - - - - - - - - YES - YES - - - - 268 - {{20, 10}, {97, 19}} - - - - _NS:9 - YES - - -2080374784 - 134217728 - Send message - - LucidaGrande - 12 - 16 - - _NS:9 - - -2038153216 - 164 - - - 400 - 75 - - - - - 268 - {{125, 10}, {86, 19}} - - - _NS:9 - YES - - -2080374784 - 134217728 - Call Handler - - _NS:9 - - -2038153216 - 164 - - - 400 - 75 - - - - {480, 360} - - - - - {{0, 0}, {1280, 778}} - {10000000000000, 10000000000000} - YES - - - AppDelegate - - - NSFontManager - - - - 256 - - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple URL pasteboard type - Apple Web Archive pasteboard type - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - WebURLsWithTitlesPboardType - public.png - public.url - public.url-name - - {254, 200} - - - - _NS:9 - - - - YES - YES - - - - - - - terminate: - - - - 449 - - - - orderFrontStandardAboutPanel: - - - - 142 - - - - delegate - - - - 495 - - - - performMiniaturize: - - - - 37 - - - - arrangeInFront: - - - - 39 - - - - print: - - - - 86 - - - - runPageLayout: - - - - 87 - - - - clearRecentDocuments: - - - - 127 - - - - performClose: - - - - 193 - - - - toggleContinuousSpellChecking: - - - - 222 - - - - undo: - - - - 223 - - - - copy: - - - - 224 - - - - checkSpelling: - - - - 225 - - - - paste: - - - - 226 - - - - stopSpeaking: - - - - 227 - - - - cut: - - - - 228 - - - - showGuessPanel: - - - - 230 - - - - redo: - - - - 231 - - - - selectAll: - - - - 232 - - - - startSpeaking: - - - - 233 - - - - delete: - - - - 235 - - - - performZoom: - - - - 240 - - - - performFindPanelAction: - - - - 241 - - - - centerSelectionInVisibleArea: - - - - 245 - - - - toggleGrammarChecking: - - - - 347 - - - - toggleSmartInsertDelete: - - - - 355 - - - - toggleAutomaticQuoteSubstitution: - - - - 356 - - - - toggleAutomaticLinkDetection: - - - - 357 - - - - saveDocument: - - - - 362 - - - - revertDocumentToSaved: - - - - 364 - - - - runToolbarCustomizationPalette: - - - - 365 - - - - toggleToolbarShown: - - - - 366 - - - - hide: - - - - 367 - - - - hideOtherApplications: - - - - 368 - - - - unhideAllApplications: - - - - 370 - - - - newDocument: - - - - 373 - - - - openDocument: - - - - 374 - - - - raiseBaseline: - - - - 426 - - - - lowerBaseline: - - - - 427 - - - - copyFont: - - - - 428 - - - - subscript: - - - - 429 - - - - superscript: - - - - 430 - - - - tightenKerning: - - - - 431 - - - - underline: - - - - 432 - - - - orderFrontColorPanel: - - - - 433 - - - - useAllLigatures: - - - - 434 - - - - loosenKerning: - - - - 435 - - - - pasteFont: - - - - 436 - - - - unscript: - - - - 437 - - - - useStandardKerning: - - - - 438 - - - - useStandardLigatures: - - - - 439 - - - - turnOffLigatures: - - - - 440 - - - - turnOffKerning: - - - - 441 - - - - toggleAutomaticSpellingCorrection: - - - - 456 - - - - orderFrontSubstitutionsPanel: - - - - 458 - - - - toggleAutomaticDashSubstitution: - - - - 461 - - - - toggleAutomaticTextReplacement: - - - - 463 - - - - uppercaseWord: - - - - 464 - - - - capitalizeWord: - - - - 467 - - - - lowercaseWord: - - - - 468 - - - - pasteAsPlainText: - - - - 486 - - - - performFindPanelAction: - - - - 487 - - - - performFindPanelAction: - - - - 488 - - - - performFindPanelAction: - - - - 489 - - - - showHelp: - - - - 493 - - - - alignCenter: - - - - 518 - - - - pasteRuler: - - - - 519 - - - - toggleRuler: - - - - 520 - - - - alignRight: - - - - 521 - - - - copyRuler: - - - - 522 - - - - alignJustified: - - - - 523 - - - - alignLeft: - - - - 524 - - - - makeBaseWritingDirectionNatural: - - - - 525 - - - - makeBaseWritingDirectionLeftToRight: - - - - 526 - - - - makeBaseWritingDirectionRightToLeft: - - - - 527 - - - - makeTextWritingDirectionNatural: - - - - 528 - - - - makeTextWritingDirectionLeftToRight: - - - - 529 - - - - makeTextWritingDirectionRightToLeft: - - - - 530 - - - - performFindPanelAction: - - - - 535 - - - - addFontTrait: - - - - 421 - - - - addFontTrait: - - - - 422 - - - - modifyFont: - - - - 423 - - - - orderFrontFontPanel: - - - - 424 - - - - modifyFont: - - - - 425 - - - - window - - - - 532 - - - - webView - - - - 543 - - - - sendMessage: - - - - 555 - - - - callHandler: - - - - 556 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 29 - - - - - - - - - - - - - - 19 - - - - - - - - 56 - - - - - - - - 217 - - - - - - - - 83 - - - - - - - - 81 - - - - - - - - - - - - - - - - - 75 - - - - - 78 - - - - - 72 - - - - - 82 - - - - - 124 - - - - - - - - 77 - - - - - 73 - - - - - 79 - - - - - 112 - - - - - 74 - - - - - 125 - - - - - - - - 126 - - - - - 205 - - - - - - - - - - - - - - - - - - - - - - 202 - - - - - 198 - - - - - 207 - - - - - 214 - - - - - 199 - - - - - 203 - - - - - 197 - - - - - 206 - - - - - 215 - - - - - 218 - - - - - - - - 216 - - - - - - - - 200 - - - - - - - - - - - - - 219 - - - - - 201 - - - - - 204 - - - - - 220 - - - - - - - - - - - - - 213 - - - - - 210 - - - - - 221 - - - - - 208 - - - - - 209 - - - - - 57 - - - - - - - - - - - - - - - - - - 58 - - - - - 134 - - - - - 150 - - - - - 136 - - - - - 144 - - - - - 129 - - - - - 143 - - - - - 236 - - - - - 131 - - - - - - - - 149 - - - - - 145 - - - - - 130 - - - - - 24 - - - - - - - - - - - 92 - - - - - 5 - - - - - 239 - - - - - 23 - - - - - 295 - - - - - - - - 296 - - - - - - - - - 297 - - - - - 298 - - - - - 211 - - - - - - - - 212 - - - - - - - - - 195 - - - - - 196 - - - - - 346 - - - - - 348 - - - - - - - - 349 - - - - - - - - - - - - - - 350 - - - - - 351 - - - - - 354 - - - - - 371 - - - - - - - - 372 - - - - - 11 - 0 - - 11 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - - - - 5 - 0 - - 6 - 1 - - 8 - - 1000 - - 6 - 24 - 3 - - - - 3 - 0 - - 4 - 1 - - 8 - - 1000 - - 6 - 24 - 3 - - - - 5 - 0 - - 5 - 1 - - 20 - - 1000 - - 8 - 29 - 3 - - - - 6 - 0 - - 6 - 1 - - 0.0 - - 1000 - - 8 - 29 - 3 - - - - 3 - 0 - - 3 - 1 - - 0.0 - - 1000 - - 8 - 29 - 3 - - - - 5 - 0 - - 5 - 1 - - 0.0 - - 1000 - - 8 - 29 - 3 - - - - - - - - - 375 - - - - - - - - 376 - - - - - - - - - 377 - - - - - - - - 388 - - - - - - - - - - - - - - - - - - - - - - - 389 - - - - - 390 - - - - - 391 - - - - - 392 - - - - - 393 - - - - - 394 - - - - - 395 - - - - - 396 - - - - - 397 - - - - - - - - 398 - - - - - - - - 399 - - - - - - - - 400 - - - - - 401 - - - - - 402 - - - - - 403 - - - - - 404 - - - - - 405 - - - - - - - - - - - - 406 - - - - - 407 - - - - - 408 - - - - - 409 - - - - - 410 - - - - - 411 - - - - - - - - - - 412 - - - - - 413 - - - - - 414 - - - - - 415 - - - - - - - - - - - 416 - - - - - 417 - - - - - 418 - - - - - 419 - - - - - 420 - - - - - 450 - - - - - - - - 451 - - - - - - - - - - 452 - - - - - 453 - - - - - 454 - - - - - 457 - - - - - 459 - - - - - 460 - - - - - 462 - - - - - 465 - - - - - 466 - - - - - 485 - - - - - 490 - - - - - - - - 491 - - - - - - - - 492 - - - - - 494 - - - - - 496 - - - - - - - - 497 - - - - - - - - - - - - - - - - - 498 - - - - - 499 - - - - - 500 - - - - - 501 - - - - - 502 - - - - - 503 - - - - - - - - 504 - - - - - 505 - - - - - 506 - - - - - 507 - - - - - 508 - - - - - - - - - - - - - - - - 509 - - - - - 510 - - - - - 511 - - - - - 512 - - - - - 513 - - - - - 514 - - - - - 515 - - - - - 516 - - - - - 517 - - - - - 534 - - - - - 536 - - - - - 8 - 0 - - 0 - 1 - - 323 - - 1000 - - 3 - 9 - 1 - - - - - - 539 - - - - - 540 - - - - - 542 - - - - - 544 - - - - - 545 - - - - - - - - 546 - - - - - 550 - - - - - 551 - - - - - - - - 552 - - - - - 554 - - - - - 557 - - - - - 558 - - - - - 559 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{380, 496}, {480, 360}} - - - - - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - com.apple.WebKitIBPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 559 - - - - - AppDelegate - NSObject - - id - id - - - - callHandler: - id - - - sendMessage: - id - - - - WebView - NSWindow - - - - webView - WebView - - - window - NSWindow - - - - IBProjectSource - ./Classes/AppDelegate.h - - - - NSLayoutConstraint - NSObject - - IBProjectSource - ./Classes/NSLayoutConstraint.h - - - - - 0 - IBCocoaFramework - YES - 3 - - {11, 11} - {10, 3} - - YES - - diff --git a/Example Apps/ExampleApp-OSX/main.m b/Example Apps/ExampleApp-OSX/main.m deleted file mode 100644 index 04d99dab..00000000 --- a/Example Apps/ExampleApp-OSX/main.m +++ /dev/null @@ -1,6 +0,0 @@ -#import - -int main(int argc, char *argv[]) -{ - return NSApplicationMain(argc, (const char **)argv); -} From b85f3ff273be12aec831808be7c681206493ea78 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Sat, 8 Jun 2013 19:58:03 -0700 Subject: [PATCH 034/285] Create an OS X example app that creates everything in code --- .../ExampleApp-OSX.xcodeproj/project.pbxproj | 340 ++++++++++++++++++ Example Apps/ExampleApp-OSX/AppDelegate.h | 15 + Example Apps/ExampleApp-OSX/AppDelegate.m | 87 +++++ .../ExampleApp-OSX/ExampleApp-OSX-Info.plist | 34 ++ .../ExampleApp-OSX/ExampleApp-OSX-Prefix.pch | 7 + Example Apps/ExampleApp-OSX/ExampleApp.html | 66 ++++ .../ExampleApp-OSX/en.lproj/Credits.rtf | 29 ++ .../ExampleApp-OSX/en.lproj/InfoPlist.strings | 2 + Example Apps/ExampleApp-OSX/main.m | 14 + 9 files changed, 594 insertions(+) create mode 100644 Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj create mode 100644 Example Apps/ExampleApp-OSX/AppDelegate.h create mode 100644 Example Apps/ExampleApp-OSX/AppDelegate.m create mode 100644 Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist create mode 100644 Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch create mode 100644 Example Apps/ExampleApp-OSX/ExampleApp.html create mode 100644 Example Apps/ExampleApp-OSX/en.lproj/Credits.rtf create mode 100644 Example Apps/ExampleApp-OSX/en.lproj/InfoPlist.strings create mode 100644 Example Apps/ExampleApp-OSX/main.m diff --git a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj new file mode 100644 index 00000000..248a1e84 --- /dev/null +++ b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj @@ -0,0 +1,340 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 2C136A2517641106004C7401 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C136A2417641106004C7401 /* Cocoa.framework */; }; + 2C136A2F17641106004C7401 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A2D17641106004C7401 /* InfoPlist.strings */; }; + 2C136A3117641106004C7401 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C136A3017641106004C7401 /* main.m */; }; + 2C136A3517641106004C7401 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A3317641106004C7401 /* Credits.rtf */; }; + 2C136A3817641106004C7401 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C136A3717641106004C7401 /* AppDelegate.m */; }; + 2C136A4217641236004C7401 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C136A4117641236004C7401 /* WebKit.framework */; }; + 2C136A4E176421B9004C7401 /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A4D176421B9004C7401 /* ExampleApp.html */; }; + 2C136A5617642680004C7401 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A5117642680004C7401 /* WebViewJavascriptBridge.js.txt */; }; + 2C136A5717642680004C7401 /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C136A5317642680004C7401 /* WebViewJavascriptBridgeAbstract.m */; }; + 2C136A5817642680004C7401 /* WebViewJavascriptBridge_OSX.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C136A5517642680004C7401 /* WebViewJavascriptBridge_OSX.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 2C136A2117641106004C7401 /* ExampleApp-OSX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ExampleApp-OSX.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2C136A2417641106004C7401 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + 2C136A2717641106004C7401 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + 2C136A2817641106004C7401 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + 2C136A2917641106004C7401 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 2C136A2C17641106004C7401 /* ExampleApp-OSX-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ExampleApp-OSX-Info.plist"; sourceTree = ""; }; + 2C136A2E17641106004C7401 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 2C136A3017641106004C7401 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2C136A3217641106004C7401 /* ExampleApp-OSX-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ExampleApp-OSX-Prefix.pch"; sourceTree = ""; }; + 2C136A3417641106004C7401 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; + 2C136A3617641106004C7401 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 2C136A3717641106004C7401 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 2C136A4117641236004C7401 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + 2C136A4D176421B9004C7401 /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = ""; }; + 2C136A5117642680004C7401 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; + 2C136A5217642680004C7401 /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; + 2C136A5317642680004C7401 /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; + 2C136A5417642680004C7401 /* WebViewJavascriptBridge_OSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_OSX.h; sourceTree = ""; }; + 2C136A5517642680004C7401 /* WebViewJavascriptBridge_OSX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_OSX.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 2C136A1E17641106004C7401 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2C136A4217641236004C7401 /* WebKit.framework in Frameworks */, + 2C136A2517641106004C7401 /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2C136A1817641106004C7401 = { + isa = PBXGroup; + children = ( + 2C136A4117641236004C7401 /* WebKit.framework */, + 2C136A2A17641106004C7401 /* ExampleApp-OSX */, + 2C136A2317641106004C7401 /* Frameworks */, + 2C136A2217641106004C7401 /* Products */, + ); + sourceTree = ""; + }; + 2C136A2217641106004C7401 /* Products */ = { + isa = PBXGroup; + children = ( + 2C136A2117641106004C7401 /* ExampleApp-OSX.app */, + ); + name = Products; + sourceTree = ""; + }; + 2C136A2317641106004C7401 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2C136A2417641106004C7401 /* Cocoa.framework */, + 2C136A2617641106004C7401 /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2C136A2617641106004C7401 /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 2C136A2717641106004C7401 /* AppKit.framework */, + 2C136A2817641106004C7401 /* CoreData.framework */, + 2C136A2917641106004C7401 /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 2C136A2A17641106004C7401 /* ExampleApp-OSX */ = { + isa = PBXGroup; + children = ( + 2C136A3617641106004C7401 /* AppDelegate.h */, + 2C136A3717641106004C7401 /* AppDelegate.m */, + 2C136A4D176421B9004C7401 /* ExampleApp.html */, + 2C136A4F17642680004C7401 /* WebViewJavascriptBridge_OSX */, + 2C136A2B17641106004C7401 /* Supporting Files */, + ); + path = "ExampleApp-OSX"; + sourceTree = ""; + }; + 2C136A2B17641106004C7401 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 2C136A2C17641106004C7401 /* ExampleApp-OSX-Info.plist */, + 2C136A2D17641106004C7401 /* InfoPlist.strings */, + 2C136A3017641106004C7401 /* main.m */, + 2C136A3217641106004C7401 /* ExampleApp-OSX-Prefix.pch */, + 2C136A3317641106004C7401 /* Credits.rtf */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 2C136A4F17642680004C7401 /* WebViewJavascriptBridge_OSX */ = { + isa = PBXGroup; + children = ( + 2C136A5017642680004C7401 /* WebViewJavascriptAbstract */, + 2C136A5417642680004C7401 /* WebViewJavascriptBridge_OSX.h */, + 2C136A5517642680004C7401 /* WebViewJavascriptBridge_OSX.m */, + ); + name = WebViewJavascriptBridge_OSX; + path = ../../WebViewJavascriptBridge_OSX; + sourceTree = ""; + }; + 2C136A5017642680004C7401 /* WebViewJavascriptAbstract */ = { + isa = PBXGroup; + children = ( + 2C136A5117642680004C7401 /* WebViewJavascriptBridge.js.txt */, + 2C136A5217642680004C7401 /* WebViewJavascriptBridgeAbstract.h */, + 2C136A5317642680004C7401 /* WebViewJavascriptBridgeAbstract.m */, + ); + path = WebViewJavascriptAbstract; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 2C136A2017641106004C7401 /* ExampleApp-OSX */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2C136A3E17641106004C7401 /* Build configuration list for PBXNativeTarget "ExampleApp-OSX" */; + buildPhases = ( + 2C136A1D17641106004C7401 /* Sources */, + 2C136A1E17641106004C7401 /* Frameworks */, + 2C136A1F17641106004C7401 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "ExampleApp-OSX"; + productName = "ExampleApp-OSX"; + productReference = 2C136A2117641106004C7401 /* ExampleApp-OSX.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 2C136A1917641106004C7401 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0460; + ORGANIZATIONNAME = "Marcus Westin"; + }; + buildConfigurationList = 2C136A1C17641106004C7401 /* Build configuration list for PBXProject "ExampleApp-OSX" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 2C136A1817641106004C7401; + productRefGroup = 2C136A2217641106004C7401 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2C136A2017641106004C7401 /* ExampleApp-OSX */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 2C136A1F17641106004C7401 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2C136A2F17641106004C7401 /* InfoPlist.strings in Resources */, + 2C136A3517641106004C7401 /* Credits.rtf in Resources */, + 2C136A4E176421B9004C7401 /* ExampleApp.html in Resources */, + 2C136A5617642680004C7401 /* WebViewJavascriptBridge.js.txt in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2C136A1D17641106004C7401 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2C136A3117641106004C7401 /* main.m in Sources */, + 2C136A3817641106004C7401 /* AppDelegate.m in Sources */, + 2C136A5717642680004C7401 /* WebViewJavascriptBridgeAbstract.m in Sources */, + 2C136A5817642680004C7401 /* WebViewJavascriptBridge_OSX.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 2C136A2D17641106004C7401 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 2C136A2E17641106004C7401 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 2C136A3317641106004C7401 /* Credits.rtf */ = { + isa = PBXVariantGroup; + children = ( + 2C136A3417641106004C7401 /* en */, + ); + name = Credits.rtf; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 2C136A3C17641106004C7401 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 2C136A3D17641106004C7401 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + SDKROOT = macosx; + }; + name = Release; + }; + 2C136A3F17641106004C7401 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ExampleApp-OSX/ExampleApp-OSX-Prefix.pch"; + INFOPLIST_FILE = "ExampleApp-OSX/ExampleApp-OSX-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 2C136A4017641106004C7401 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ExampleApp-OSX/ExampleApp-OSX-Prefix.pch"; + INFOPLIST_FILE = "ExampleApp-OSX/ExampleApp-OSX-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2C136A1C17641106004C7401 /* Build configuration list for PBXProject "ExampleApp-OSX" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2C136A3C17641106004C7401 /* Debug */, + 2C136A3D17641106004C7401 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2C136A3E17641106004C7401 /* Build configuration list for PBXNativeTarget "ExampleApp-OSX" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2C136A3F17641106004C7401 /* Debug */, + 2C136A4017641106004C7401 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 2C136A1917641106004C7401 /* Project object */; +} diff --git a/Example Apps/ExampleApp-OSX/AppDelegate.h b/Example Apps/ExampleApp-OSX/AppDelegate.h new file mode 100644 index 00000000..6d91daf4 --- /dev/null +++ b/Example Apps/ExampleApp-OSX/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// ExampleApp-OSX +// +// Created by Marcus Westin on 6/8/13. +// Copyright (c) 2013 Marcus Westin. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + +@property (assign) IBOutlet NSWindow *window; + +@end diff --git a/Example Apps/ExampleApp-OSX/AppDelegate.m b/Example Apps/ExampleApp-OSX/AppDelegate.m new file mode 100644 index 00000000..03724e00 --- /dev/null +++ b/Example Apps/ExampleApp-OSX/AppDelegate.m @@ -0,0 +1,87 @@ +// +// AppDelegate.m +// ExampleApp-OSX +// +// Created by Marcus Westin on 6/8/13. +// Copyright (c) 2013 Marcus Westin. All rights reserved. +// + +#import "AppDelegate.h" +#import +#import "WebViewJavascriptBridge_OSX.h" + +@implementation AppDelegate { + WebView* _webView; + WebViewJavascriptBridge* _bridge; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + [self _createViews]; + [self _createBridge]; + [self _createObjcButtons]; + [self _loadPage]; +} + +- (void)_createBridge { + _bridge = [WebViewJavascriptBridge bridgeForWebView:_webView handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"ObjC received message from JS: %@", data); + responseCallback(@"Response for message from ObjC"); + }]; + + [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"testObjcCallback called: %@", data); + responseCallback(@"Response from testObjcCallback"); + }]; + + [_bridge send:@"A string sent from ObjC before Webview has loaded." responseCallback:^(id responseData) { + NSLog(@"objc got response! %@", responseData); + }]; + + [_bridge callHandler:@"testJavascriptHandler" data:[NSDictionary dictionaryWithObject:@"before ready" forKey:@"foo"]]; +} + +- (void)_createObjcButtons { + NSButton *messageButton = [[NSButton alloc] initWithFrame:NSMakeRect(5, 0, 120, 40)]; + [messageButton setTitle:@"Send message"]; + [messageButton setBezelStyle:NSRoundedBezelStyle]; + [messageButton setTarget:self]; + [messageButton setAction:@selector(_sendMessage)]; + [_webView addSubview:messageButton]; + + NSButton *callbackButton = [[NSButton alloc] initWithFrame:NSMakeRect(120, 0, 120, 40)]; + [callbackButton setTitle:@"Call handler"]; + [callbackButton setBezelStyle:NSRoundedBezelStyle]; + [callbackButton setTarget:self]; + [callbackButton setAction:@selector(_callHandler)]; + [_webView addSubview:callbackButton]; +} + +- (void)_sendMessage { + [_bridge send:@"A string sent from ObjC to JS" responseCallback:^(id response) { + NSLog(@"sendMessage got response: %@", response); + }]; +} + +- (void)_callHandler { + NSDictionary* data = [NSDictionary dictionaryWithObject:@"Hi there, JS!" forKey:@"greetingFromObjC"]; + [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { + NSLog(@"testJavascriptHandler responded: %@", response); + }]; +} + +- (void)_createViews { + NSView* contentView = _window.contentView; + _webView = [[WebView alloc] initWithFrame:contentView.frame]; + [_webView setAutoresizingMask:(NSViewHeightSizable | NSViewWidthSizable)]; + [contentView addSubview:_webView]; +} + +- (void)_loadPage { + NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; + NSString* html = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; + [[_webView mainFrame] loadHTMLString:html baseURL:nil]; +} + + +@end diff --git a/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist new file mode 100644 index 00000000..14097880 --- /dev/null +++ b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + WebViewJavascriptBridge.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + ${MACOSX_DEPLOYMENT_TARGET} + NSHumanReadableCopyright + Copyright © 2013 Marcus Westin. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch new file mode 100644 index 00000000..32daebd5 --- /dev/null +++ b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'ExampleApp-OSX' target in the 'ExampleApp-OSX' project +// + +#ifdef __OBJC__ + #import +#endif diff --git a/Example Apps/ExampleApp-OSX/ExampleApp.html b/Example Apps/ExampleApp-OSX/ExampleApp.html new file mode 100644 index 00000000..9272e3f3 --- /dev/null +++ b/Example Apps/ExampleApp-OSX/ExampleApp.html @@ -0,0 +1,66 @@ + + + + +

WebViewJavascriptBridge Demo

+ +
+ diff --git a/Example Apps/ExampleApp-OSX/en.lproj/Credits.rtf b/Example Apps/ExampleApp-OSX/en.lproj/Credits.rtf new file mode 100644 index 00000000..46576ef2 --- /dev/null +++ b/Example Apps/ExampleApp-OSX/en.lproj/Credits.rtf @@ -0,0 +1,29 @@ +{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} +{\colortbl;\red255\green255\blue255;} +\paperw9840\paperh8400 +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\b\fs24 \cf0 Engineering: +\b0 \ + Some people\ +\ + +\b Human Interface Design: +\b0 \ + Some other people\ +\ + +\b Testing: +\b0 \ + Hopefully not nobody\ +\ + +\b Documentation: +\b0 \ + Whoever\ +\ + +\b With special thanks to: +\b0 \ + Mom\ +} diff --git a/Example Apps/ExampleApp-OSX/en.lproj/InfoPlist.strings b/Example Apps/ExampleApp-OSX/en.lproj/InfoPlist.strings new file mode 100644 index 00000000..477b28ff --- /dev/null +++ b/Example Apps/ExampleApp-OSX/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/Example Apps/ExampleApp-OSX/main.m b/Example Apps/ExampleApp-OSX/main.m new file mode 100644 index 00000000..0999e46a --- /dev/null +++ b/Example Apps/ExampleApp-OSX/main.m @@ -0,0 +1,14 @@ +// +// main.m +// ExampleApp-OSX +// +// Created by Marcus Westin on 6/8/13. +// Copyright (c) 2013 Marcus Westin. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **)argv); +} From a21cdd4e17bd17068e525c16b0f269c4a063b20d Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Sat, 8 Jun 2013 20:00:16 -0700 Subject: [PATCH 035/285] Use the same ExampleApp.html file in the OSX example app as the iOS example app uses --- .../ExampleApp-OSX.xcodeproj/project.pbxproj | 8 +-- Example Apps/ExampleApp-OSX/ExampleApp.html | 66 ------------------- 2 files changed, 4 insertions(+), 70 deletions(-) delete mode 100644 Example Apps/ExampleApp-OSX/ExampleApp.html diff --git a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj index 248a1e84..34b8c107 100644 --- a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj @@ -13,10 +13,10 @@ 2C136A3517641106004C7401 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A3317641106004C7401 /* Credits.rtf */; }; 2C136A3817641106004C7401 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C136A3717641106004C7401 /* AppDelegate.m */; }; 2C136A4217641236004C7401 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C136A4117641236004C7401 /* WebKit.framework */; }; - 2C136A4E176421B9004C7401 /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A4D176421B9004C7401 /* ExampleApp.html */; }; 2C136A5617642680004C7401 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A5117642680004C7401 /* WebViewJavascriptBridge.js.txt */; }; 2C136A5717642680004C7401 /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C136A5317642680004C7401 /* WebViewJavascriptBridgeAbstract.m */; }; 2C136A5817642680004C7401 /* WebViewJavascriptBridge_OSX.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C136A5517642680004C7401 /* WebViewJavascriptBridge_OSX.m */; }; + 2C136A5A17642704004C7401 /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A5917642704004C7401 /* ExampleApp.html */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -33,12 +33,12 @@ 2C136A3617641106004C7401 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 2C136A3717641106004C7401 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 2C136A4117641236004C7401 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; - 2C136A4D176421B9004C7401 /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = ""; }; 2C136A5117642680004C7401 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; 2C136A5217642680004C7401 /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; 2C136A5317642680004C7401 /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; 2C136A5417642680004C7401 /* WebViewJavascriptBridge_OSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_OSX.h; sourceTree = ""; }; 2C136A5517642680004C7401 /* WebViewJavascriptBridge_OSX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_OSX.m; sourceTree = ""; }; + 2C136A5917642704004C7401 /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -96,7 +96,7 @@ children = ( 2C136A3617641106004C7401 /* AppDelegate.h */, 2C136A3717641106004C7401 /* AppDelegate.m */, - 2C136A4D176421B9004C7401 /* ExampleApp.html */, + 2C136A5917642704004C7401 /* ExampleApp.html */, 2C136A4F17642680004C7401 /* WebViewJavascriptBridge_OSX */, 2C136A2B17641106004C7401 /* Supporting Files */, ); @@ -189,8 +189,8 @@ files = ( 2C136A2F17641106004C7401 /* InfoPlist.strings in Resources */, 2C136A3517641106004C7401 /* Credits.rtf in Resources */, - 2C136A4E176421B9004C7401 /* ExampleApp.html in Resources */, 2C136A5617642680004C7401 /* WebViewJavascriptBridge.js.txt in Resources */, + 2C136A5A17642704004C7401 /* ExampleApp.html in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Example Apps/ExampleApp-OSX/ExampleApp.html b/Example Apps/ExampleApp-OSX/ExampleApp.html deleted file mode 100644 index 9272e3f3..00000000 --- a/Example Apps/ExampleApp-OSX/ExampleApp.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - -

WebViewJavascriptBridge Demo

- -
- From 668573f8e740775c08c0c41333289b6172d91a5e Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 14 Jun 2013 11:14:52 -0700 Subject: [PATCH 036/285] Remove numRequestsLoading from the OSX bridge. Since didFinishLoadForFrame fires when the entire document has loaded (rather than when any individual resource has loaded), numRequestsLoading is simply not required for OS X and causes problems --- .../WebViewJavascriptBridge_OSX.m | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m index b442802a..5a29a0a3 100644 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m +++ b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m @@ -1,11 +1,5 @@ #import "WebViewJavascriptBridge_OSX.h" -@interface WebViewJavascriptBridge () - -@property (nonatomic, assign) NSUInteger numRequestsLoading; - -@end - @implementation WebViewJavascriptBridge + (instancetype)bridgeForWebView:(WebView *)webView handler:(WVJBHandler)handler { @@ -38,9 +32,7 @@ - (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame { if (webView != self.webView) { return; } - self.numRequestsLoading--; - - if (self.numRequestsLoading == 0 && ![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { + if (![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; [webView stringByEvaluatingJavaScriptFromString:js]; @@ -62,8 +54,6 @@ - (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame - (void)webView:(WebView *)webView didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { if (webView != self.webView) { return; } - self.numRequestsLoading--; - __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) { [strongDelegate webView:strongDelegate didFailLoadWithError:error forFrame:frame]; @@ -101,8 +91,6 @@ - (void)webView:(WebView *)webView didCommitLoadForFrame:(WebFrame *)frame { - (NSURLRequest *)webView:(WebView *)webView resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource { if (webView != self.webView) { return request; } - self.numRequestsLoading++; - __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) { return [strongDelegate webView:webView resource:identifier willSendRequest:request redirectResponse:redirectResponse fromDataSource:dataSource]; From baf4a06d0867d11a856be578b9d9f8c19b8e4203 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 14 Jun 2013 11:20:11 -0700 Subject: [PATCH 037/285] Import WebKit in conditional OSX macro of WebViewJavascriptBridgeAbstract to avoid compiler warnings about stringByEvaluatingJavaScriptFromString: selector being undefined --- .../WebViewJavascriptBridgeAbstract.h | 1 + WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h index de80ba9d..30301c57 100644 --- a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h +++ b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h @@ -6,6 +6,7 @@ #define WEAK_FALLBACK weak #elif TARGET_OS_MAC && defined(__MAC_10_7) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_7) #define WEAK_FALLBACK weak + #import #else #define WEAK_FALLBACK unsafe_unretained #endif diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h index d674fa20..41e5305e 100644 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h +++ b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h @@ -1,4 +1,3 @@ -#import #import "WebViewJavascriptBridgeAbstract.h" @interface WebViewJavascriptBridge : WebViewJavascriptBridgeAbstract From 57ee322a4c5310eadd28b28f4d8522cd54123301 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 14 Jun 2013 13:16:26 -0700 Subject: [PATCH 038/285] Simplify setup and file organization by doing away with the Abstract/iOS/OSX seperation. Instead, we manage the iOS/OSX platform specific part using macros --- .../ExampleApp-OSX.xcodeproj/project.pbxproj | 42 +- Example Apps/ExampleApp-OSX/AppDelegate.m | 2 +- .../ExampleApp-iOS.xcodeproj/project.pbxproj | 52 +-- .../ExampleApp-iOS/ExampleAppDelegate.h | 2 +- README.md | 7 +- WebViewJavascriptBridge.podspec | 4 +- .../WebViewJavascriptBridge.h | 51 +++ .../WebViewJavascriptBridge.js.txt | 0 .../WebViewJavascriptBridge.m | 378 ++++++++++++++++++ .../WebViewJavascriptBridgeAbstract.h | 48 --- .../WebViewJavascriptBridgeAbstract.m | 171 -------- .../WebViewJavascriptAbstract | 1 - .../WebViewJavascriptBridge_OSX.h | 11 - .../WebViewJavascriptBridge_OSX.m | 102 ----- .../WebViewJavascriptAbstract | 1 - .../WebViewJavascriptBridge_iOS.h | 12 - .../WebViewJavascriptBridge_iOS.m | 99 ----- 17 files changed, 468 insertions(+), 515 deletions(-) create mode 100644 WebViewJavascriptBridge/WebViewJavascriptBridge.h rename {WebViewJavascriptBridgeAbstract => WebViewJavascriptBridge}/WebViewJavascriptBridge.js.txt (100%) create mode 100644 WebViewJavascriptBridge/WebViewJavascriptBridge.m delete mode 100644 WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h delete mode 100755 WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m delete mode 120000 WebViewJavascriptBridge_OSX/WebViewJavascriptAbstract delete mode 100644 WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h delete mode 100644 WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m delete mode 120000 WebViewJavascriptBridge_iOS/WebViewJavascriptAbstract delete mode 100644 WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h delete mode 100644 WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m diff --git a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj index 34b8c107..18313cd6 100644 --- a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj @@ -13,10 +13,9 @@ 2C136A3517641106004C7401 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A3317641106004C7401 /* Credits.rtf */; }; 2C136A3817641106004C7401 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C136A3717641106004C7401 /* AppDelegate.m */; }; 2C136A4217641236004C7401 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C136A4117641236004C7401 /* WebKit.framework */; }; - 2C136A5617642680004C7401 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A5117642680004C7401 /* WebViewJavascriptBridge.js.txt */; }; - 2C136A5717642680004C7401 /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C136A5317642680004C7401 /* WebViewJavascriptBridgeAbstract.m */; }; - 2C136A5817642680004C7401 /* WebViewJavascriptBridge_OSX.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C136A5517642680004C7401 /* WebViewJavascriptBridge_OSX.m */; }; 2C136A5A17642704004C7401 /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A5917642704004C7401 /* ExampleApp.html */; }; + 2C1562C5176BA9FF00B4AE50 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2C1562C3176BA9FF00B4AE50 /* WebViewJavascriptBridge.js.txt */; }; + 2C1562C6176BA9FF00B4AE50 /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1562C4176BA9FF00B4AE50 /* WebViewJavascriptBridge.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -33,12 +32,10 @@ 2C136A3617641106004C7401 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 2C136A3717641106004C7401 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 2C136A4117641236004C7401 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; - 2C136A5117642680004C7401 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; - 2C136A5217642680004C7401 /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; - 2C136A5317642680004C7401 /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; - 2C136A5417642680004C7401 /* WebViewJavascriptBridge_OSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_OSX.h; sourceTree = ""; }; - 2C136A5517642680004C7401 /* WebViewJavascriptBridge_OSX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_OSX.m; sourceTree = ""; }; 2C136A5917642704004C7401 /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = SOURCE_ROOT; }; + 2C1562C2176BA9FF00B4AE50 /* WebViewJavascriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge.h; sourceTree = ""; }; + 2C1562C3176BA9FF00B4AE50 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; + 2C1562C4176BA9FF00B4AE50 /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -97,7 +94,7 @@ 2C136A3617641106004C7401 /* AppDelegate.h */, 2C136A3717641106004C7401 /* AppDelegate.m */, 2C136A5917642704004C7401 /* ExampleApp.html */, - 2C136A4F17642680004C7401 /* WebViewJavascriptBridge_OSX */, + 2C1562C1176BA9FF00B4AE50 /* WebViewJavascriptBridge */, 2C136A2B17641106004C7401 /* Supporting Files */, ); path = "ExampleApp-OSX"; @@ -115,25 +112,15 @@ name = "Supporting Files"; sourceTree = ""; }; - 2C136A4F17642680004C7401 /* WebViewJavascriptBridge_OSX */ = { + 2C1562C1176BA9FF00B4AE50 /* WebViewJavascriptBridge */ = { isa = PBXGroup; children = ( - 2C136A5017642680004C7401 /* WebViewJavascriptAbstract */, - 2C136A5417642680004C7401 /* WebViewJavascriptBridge_OSX.h */, - 2C136A5517642680004C7401 /* WebViewJavascriptBridge_OSX.m */, + 2C1562C2176BA9FF00B4AE50 /* WebViewJavascriptBridge.h */, + 2C1562C3176BA9FF00B4AE50 /* WebViewJavascriptBridge.js.txt */, + 2C1562C4176BA9FF00B4AE50 /* WebViewJavascriptBridge.m */, ); - name = WebViewJavascriptBridge_OSX; - path = ../../WebViewJavascriptBridge_OSX; - sourceTree = ""; - }; - 2C136A5017642680004C7401 /* WebViewJavascriptAbstract */ = { - isa = PBXGroup; - children = ( - 2C136A5117642680004C7401 /* WebViewJavascriptBridge.js.txt */, - 2C136A5217642680004C7401 /* WebViewJavascriptBridgeAbstract.h */, - 2C136A5317642680004C7401 /* WebViewJavascriptBridgeAbstract.m */, - ); - path = WebViewJavascriptAbstract; + name = WebViewJavascriptBridge; + path = ../../WebViewJavascriptBridge; sourceTree = ""; }; /* End PBXGroup section */ @@ -187,9 +174,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2C1562C5176BA9FF00B4AE50 /* WebViewJavascriptBridge.js.txt in Resources */, 2C136A2F17641106004C7401 /* InfoPlist.strings in Resources */, 2C136A3517641106004C7401 /* Credits.rtf in Resources */, - 2C136A5617642680004C7401 /* WebViewJavascriptBridge.js.txt in Resources */, 2C136A5A17642704004C7401 /* ExampleApp.html in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -202,9 +189,8 @@ buildActionMask = 2147483647; files = ( 2C136A3117641106004C7401 /* main.m in Sources */, + 2C1562C6176BA9FF00B4AE50 /* WebViewJavascriptBridge.m in Sources */, 2C136A3817641106004C7401 /* AppDelegate.m in Sources */, - 2C136A5717642680004C7401 /* WebViewJavascriptBridgeAbstract.m in Sources */, - 2C136A5817642680004C7401 /* WebViewJavascriptBridge_OSX.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Example Apps/ExampleApp-OSX/AppDelegate.m b/Example Apps/ExampleApp-OSX/AppDelegate.m index 03724e00..d4b230c6 100644 --- a/Example Apps/ExampleApp-OSX/AppDelegate.m +++ b/Example Apps/ExampleApp-OSX/AppDelegate.m @@ -8,7 +8,7 @@ #import "AppDelegate.h" #import -#import "WebViewJavascriptBridge_OSX.h" +#import "WebViewJavascriptBridge.h" @implementation AppDelegate { WebView* _webView; diff --git a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj index 6a694a05..b71010e5 100644 --- a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj @@ -7,13 +7,12 @@ objects = { /* Begin PBXBuildFile section */ + 2C1562B5176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2C1562B4176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt */; }; + 2C1562C0176BA63500B4AE50 /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */; }; 2CA045BF17117439006DEE8B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045B717117439006DEE8B /* InfoPlist.strings */; }; 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */; }; 2CA045C317117439006DEE8B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BE17117439006DEE8B /* main.m */; }; 2CA0465C1711AC8E006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */; }; - 2CAB868B172766B000BD9ED1 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2CAB8686172766B000BD9ED1 /* WebViewJavascriptBridge.js.txt */; }; - 2CAB868C172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CAB8688172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.m */; }; - 2CAB868D172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CAB868A172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.m */; }; 2CAB869B1727684300BD9ED1 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2CAB869A1727684300BD9ED1 /* Default-568h@2x.png */; }; 2CEB3EC01602563600548120 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EBF1602563600548120 /* UIKit.framework */; }; 2CEB3EC21602563600548120 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CEB3EC11602563600548120 /* Foundation.framework */; }; @@ -21,6 +20,9 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 2C1562A8176B9F6200B4AE50 /* WebViewJavascriptBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge.h; sourceTree = ""; }; + 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge.m; sourceTree = ""; }; + 2C1562B4176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; 2CA045B817117439006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 2CA045B917117439006DEE8B /* ExampleApp-iOS-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ExampleApp-iOS-Info.plist"; sourceTree = ""; }; 2CA045BA17117439006DEE8B /* ExampleApp-iOS-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ExampleApp-iOS-Prefix.pch"; sourceTree = ""; }; @@ -28,11 +30,6 @@ 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleAppDelegate.m; sourceTree = ""; }; 2CA045BE17117439006DEE8B /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = SOURCE_ROOT; }; - 2CAB8686172766B000BD9ED1 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; - 2CAB8687172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeAbstract.h; sourceTree = ""; }; - 2CAB8688172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeAbstract.m; sourceTree = ""; }; - 2CAB8689172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_iOS.h; sourceTree = ""; }; - 2CAB868A172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_iOS.m; sourceTree = ""; }; 2CAB869A1727684300BD9ED1 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "ExampleApp-iOS/Default-568h@2x.png"; sourceTree = ""; }; 2CEB3EBB1602563600548120 /* ExampleApp-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ExampleApp-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 2CEB3EBF1602563600548120 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; @@ -54,13 +51,24 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 2C1562A7176B9F5400B4AE50 /* WebViewJavascriptBridge */ = { + isa = PBXGroup; + children = ( + 2C1562B4176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt */, + 2C1562A8176B9F6200B4AE50 /* WebViewJavascriptBridge.h */, + 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */, + ); + name = WebViewJavascriptBridge; + path = ../../WebViewJavascriptBridge; + sourceTree = ""; + }; 2CA045B617117439006DEE8B /* ExampleApp-iOS */ = { isa = PBXGroup; children = ( 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */, 2CA045BC17117439006DEE8B /* ExampleAppDelegate.h */, 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */, - 2CAB8684172766B000BD9ED1 /* WebViewJavascriptBridge_iOS */, + 2C1562A7176B9F5400B4AE50 /* WebViewJavascriptBridge */, 2CA046211711A94E006DEE8B /* Supporting Files */, ); path = "ExampleApp-iOS"; @@ -77,27 +85,6 @@ name = "Supporting Files"; sourceTree = ""; }; - 2CAB8684172766B000BD9ED1 /* WebViewJavascriptBridge_iOS */ = { - isa = PBXGroup; - children = ( - 2CAB8685172766B000BD9ED1 /* WebViewJavascriptAbstract */, - 2CAB8689172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.h */, - 2CAB868A172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.m */, - ); - name = WebViewJavascriptBridge_iOS; - path = ../../WebViewJavascriptBridge_iOS; - sourceTree = ""; - }; - 2CAB8685172766B000BD9ED1 /* WebViewJavascriptAbstract */ = { - isa = PBXGroup; - children = ( - 2CAB8686172766B000BD9ED1 /* WebViewJavascriptBridge.js.txt */, - 2CAB8687172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.h */, - 2CAB8688172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.m */, - ); - path = WebViewJavascriptAbstract; - sourceTree = ""; - }; 2CEB3EB01602563600548120 = { isa = PBXGroup; children = ( @@ -177,9 +164,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2C1562B5176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt in Resources */, 2CA045BF17117439006DEE8B /* InfoPlist.strings in Resources */, 2CA0465C1711AC8E006DEE8B /* ExampleApp.html in Resources */, - 2CAB868B172766B000BD9ED1 /* WebViewJavascriptBridge.js.txt in Resources */, 2CAB869B1727684300BD9ED1 /* Default-568h@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -191,10 +178,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2C1562C0176BA63500B4AE50 /* WebViewJavascriptBridge.m in Sources */, 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */, 2CA045C317117439006DEE8B /* main.m in Sources */, - 2CAB868C172766B000BD9ED1 /* WebViewJavascriptBridgeAbstract.m in Sources */, - 2CAB868D172766B000BD9ED1 /* WebViewJavascriptBridge_iOS.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h index b85422c5..5fc2d78b 100644 --- a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h +++ b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h @@ -1,5 +1,5 @@ #import -#import "WebViewJavascriptBridge_iOS.h" +#import "WebViewJavascriptBridge.h" @interface ExampleAppDelegate : UIResponder diff --git a/README.md b/README.md index e9bf51d4..3a8cec56 100644 --- a/README.md +++ b/README.md @@ -24,16 +24,13 @@ Start with the Example Apps/ folder. Open either the iOS or OSX project and hit To use a WebViewJavascriptBridge in your own project: -1) Drag the `WebViewJavascriptBridge_iOS` or `WebViewJavascriptBridge_OSX` folder into your project. +1) Drag the `WebViewJavascriptBridge` folder into your project. - In the dialog that appears, uncheck "Copy items into destination group's folder" and select "Create groups for any folders" 2) Import the header file: - // for iOS: - #import "WebViewJavascriptBridge_iOS.h" - // for OSX: - #import "WebViewJavascriptBridge_OSX.h" + #import "WebViewJavascriptBridge.h" 3) Instantiate WebViewJavascriptBridge with a UIWebView (iOS) or WebView (OSX): diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index 647d8328..2471c7fa 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -9,8 +9,8 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/marcuswestin/WebViewJavascriptBridge.git' } s.ios.platform = :ios, '5.0' s.osx.platform = :osx - s.ios.source_files = 'WebViewJavascriptBridge_iOS/*.{h,m}', 'WebViewJavascriptBridgeAbstract/*.{h,m}' - s.osx.source_files = 'WebViewJavascriptBridge_OSX/*.{h,m}', 'WebViewJavascriptBridgeAbstract/*.{h,m}' + s.ios.source_files = 'WebViewJavascriptBridge/*.{h,m}' + s.osx.source_files = 'WebViewJavascriptBridge/*.{h,m}' s.resource = 'WebViewJavascriptBridgeAbstract/WebViewJavascriptBridge.js.txt' s.ios.framework = 'UIKit' s.osx.framework = 'WebKit' diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.h b/WebViewJavascriptBridge/WebViewJavascriptBridge.h new file mode 100644 index 00000000..141cd848 --- /dev/null +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.h @@ -0,0 +1,51 @@ +// +// WebViewJavascriptBridge.h +// ExampleApp-iOS +// +// Created by Marcus Westin on 6/14/13. +// Copyright (c) 2013 Marcus Westin. All rights reserved. +// + +#import + +#define kMessageSeparator @"__WVJB_MESSAGE_SEPERATOR__" +#define kCustomProtocolScheme @"wvjbscheme" +#define kQueueHasMessage @"__WVJB_QUEUE_MESSAGE__" + +#if TARGET_OS_IPHONE && defined(__IPHONE_5_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0) + #define WVJB_WEAK_FALLBACK weak +#elif TARGET_OS_MAC && defined(__MAC_10_7) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_7) + #define WVJB_WEAK_FALLBACK weak +#else + #define WVJB_WEAK_FALLBACK unsafe_unretained +#endif + +#if defined __MAC_OS_X_VERSION_MAX_ALLOWED + #import + #define WVJB_PLATFORM_OSX + #define WVJB_WEBVIEW_TYPE WebView + #define WVJB_WEBVIEW_DELEGATE_TYPE NSObject +#elif defined __IPHONE_OS_VERSION_MAX_ALLOWED + #define WVJB_PLATFORM_IOS + #define WVJB_WEBVIEW_TYPE UIWebView + #define WVJB_WEBVIEW_DELEGATE_TYPE NSObject +#endif + +typedef void (^WVJBResponseCallback)(id responseData); +typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); + +@interface WebViewJavascriptBridge : WVJB_WEBVIEW_DELEGATE_TYPE + ++ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView handler:(WVJBHandler)handler; ++ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)handler; ++ (void)enableLogging; + +- (void)send:(id)message; +- (void)send:(id)message responseCallback:(WVJBResponseCallback)responseCallback; +- (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler; +- (void)callHandler:(NSString*)handlerName; +- (void)callHandler:(NSString*)handlerName data:(id)data; +- (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback; +- (void)reset; + +@end diff --git a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridge.js.txt b/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt similarity index 100% rename from WebViewJavascriptBridgeAbstract/WebViewJavascriptBridge.js.txt rename to WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m new file mode 100644 index 00000000..6d67b5d2 --- /dev/null +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -0,0 +1,378 @@ +// +// WebViewJavascriptBridge.m +// ExampleApp-iOS +// +// Created by Marcus Westin on 6/14/13. +// Copyright (c) 2013 Marcus Westin. All rights reserved. +// + +#import "WebViewJavascriptBridge.h" + +@implementation WebViewJavascriptBridge { + __weak WVJB_WEBVIEW_TYPE* _webView; + __weak id _webViewDelegate; + NSMutableArray* _startupMessageQueue; + NSMutableDictionary* _responseCallbacks; + NSMutableDictionary* _messageHandlers; + long _uniqueId; + WVJBHandler _messageHandler; + +#if defined WVJB_PLATFORM_IOS + NSUInteger _numRequestsLoading; +#endif + +} + +/* API + *****/ + +static bool logging = false; ++ (void)enableLogging { logging = true; } + ++ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView handler:(WVJBHandler)handler { + return [self bridgeForWebView:webView webViewDelegate:nil handler:handler]; +} + ++ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)messageHandler { + WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; + [bridge _platformSpecificSetup:webView webViewDelegate:webViewDelegate handler:messageHandler]; + [bridge reset]; + return bridge; +} + +- (void)send:(NSDictionary *)data { + [self send:data responseCallback:nil]; +} + +- (void)send:(NSDictionary *)data responseCallback:(WVJBResponseCallback)responseCallback { + [self _sendData:data responseCallback:responseCallback handlerName:nil]; +} + +- (void)callHandler:(NSString *)handlerName { + [self callHandler:handlerName data:nil responseCallback:nil]; +} + +- (void)callHandler:(NSString *)handlerName data:(id)data { + [self callHandler:handlerName data:data responseCallback:nil]; +} + +- (void)callHandler:(NSString *)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback { + [self _sendData:data responseCallback:responseCallback handlerName:handlerName]; +} + +- (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler { + _messageHandlers[handlerName] = [handler copy]; +} + +- (void)reset { + _startupMessageQueue = [NSMutableArray array]; + _responseCallbacks = [NSMutableDictionary dictionary]; + _uniqueId = 0; +} + +/* Platform agnostic internals + *****************************/ + +- (void)dealloc { + [self _platformSpecificDealloc]; + + _webView = nil; + _webViewDelegate = nil; + _startupMessageQueue = nil; + _responseCallbacks = nil; + _messageHandlers = nil; + _messageHandler = nil; +} + +- (void)_sendData:(NSDictionary *)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName { + NSMutableDictionary* message = [NSMutableDictionary dictionaryWithObject:data forKey:@"data"]; + + if (responseCallback) { + NSString* callbackId = [NSString stringWithFormat:@"objc_cb_%ld", ++_uniqueId]; + _responseCallbacks[callbackId] = [responseCallback copy]; + message[@"callbackId"] = callbackId; + } + + if (handlerName) { + message[@"handlerName"] = handlerName; + } + [self _queueMessage:message]; +} + +- (void)_queueMessage:(NSDictionary *)message { + if (_startupMessageQueue) { + [_startupMessageQueue addObject:message]; + } else { + [self _dispatchMessage:message]; + } +} + +- (void)_dispatchMessage:(NSDictionary *)message { + NSString *messageJSON = [self _serializeMessage:message]; + [self _log:@"sending" json:messageJSON]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\'" withString:@"\\\'"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r" withString:@"\\r"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\f" withString:@"\\f"]; + + NSString* javascriptCommand = [NSString stringWithFormat:@"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]; + if ([[NSThread currentThread] isMainThread]) { + [_webView stringByEvaluatingJavaScriptFromString:javascriptCommand]; + } else { + __strong WVJB_WEBVIEW_TYPE* strongWebView = _webView; + dispatch_sync(dispatch_get_main_queue(), ^{ + [strongWebView stringByEvaluatingJavaScriptFromString:javascriptCommand]; + }); + } +} + +- (void)_flushMessageQueue { + NSString *messageQueueString = [_webView stringByEvaluatingJavaScriptFromString:@"WebViewJavascriptBridge._fetchQueue();"]; + + NSArray* messages = [messageQueueString componentsSeparatedByString:kMessageSeparator]; + for (NSString *messageJSON in messages) { + [self _log:@"receivd" json:messageJSON]; + + NSDictionary* message = [self _deserializeMessageJSON:messageJSON]; + + NSString* responseId = message[@"responseId"]; + if (responseId) { + WVJBResponseCallback responseCallback = _responseCallbacks[responseId]; + responseCallback(message[@"responseData"]); + [_responseCallbacks removeObjectForKey:responseId]; + } else { + WVJBResponseCallback responseCallback = NULL; + NSString* callbackId = message[@"callbackId"]; + if (callbackId) { + responseCallback = ^(id responseData) { + NSDictionary* msg = @{ @"responseId":callbackId, @"responseData":responseData }; + [self _queueMessage:msg]; + }; + } else { + responseCallback = ^(id ignoreResponseData) { + // Do nothing + }; + } + + WVJBHandler handler; + if (message[@"handlerName"]) { + handler = _messageHandlers[message[@"handlerName"]]; + if (!handler) { return NSLog(@"WVJB Warning: No handler for %@", message[@"handlerName"]); } + } else { + handler = _messageHandler; + } + + @try { + NSDictionary* data = message[@"data"]; + if (!data || ((id)data) == [NSNull null]) { data = [NSDictionary dictionary]; } + handler(data, responseCallback); + } + @catch (NSException *exception) { + NSLog(@"WebViewJavascriptBridge: WARNING: objc handler threw. %@ %@", message, exception); + } + } + } +} + +- (NSString *)_serializeMessage:(NSDictionary *)message { +#if defined _JSONKIT_H_ + return [message JSONString]; +#else + return [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:message options:0 error:nil] encoding:NSUTF8StringEncoding]; +#endif +} + +- (NSDictionary *)_deserializeMessageJSON:(NSString *)messageJSON { +#if defined _JSONKIT_H_ + return [messageJSON objectFromJSONString]; +#else + return [NSJSONSerialization JSONObjectWithData:[messageJSON dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; +#endif +} + +- (void)_log:(NSString *)action json:(NSString *)json { + if (!logging) { return; } + if (json.length > 500) { + NSLog(@"WVJB %@: %@", action, [[json substringToIndex:500] stringByAppendingString:@" [...]"]); + } else { + NSLog(@"WVJB %@: %@", action, json); + } +} + + + +/* Platform specific internals: OSX + **********************************/ +#if defined WVJB_PLATFORM_OSX + +- (void) _platformSpecificSetup:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)messageHandler { + _messageHandler = messageHandler; + _webView = webView; + _webViewDelegate = webViewDelegate; + _messageHandlers = [NSMutableDictionary dictionary]; + + _webView.frameLoadDelegate = self; + _webView.resourceLoadDelegate = self; + _webView.policyDelegate = self; +} + +- (void) _platformSpecificDealloc { + _webView.frameLoadDelegate = nil; + _webView.resourceLoadDelegate = nil; + _webView.policyDelegate = nil; +} + +- (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame +{ + if (webView != _webView) { return; } + + if (![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { + NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; + NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; + [webView stringByEvaluatingJavaScriptFromString:js]; + } + + if (_startupMessageQueue) { + for (id queuedMessage in _startupMessageQueue) { + [self _dispatchMessage:queuedMessage]; + } + _startupMessageQueue = nil; + } + + if (_webViewDelegate && [_webViewDelegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)]) { + [_webViewDelegate webView:webView didFinishLoadForFrame:frame]; + } +} + +- (void)webView:(WebView *)webView didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { + if (webView != _webView) { return; } + + if (_webViewDelegate && [_webViewDelegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) { + [_webViewDelegate webView:webView didFailLoadWithError:error forFrame:frame]; + } +} + +- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener +{ + if (webView != _webView) { [listener use]; } + + NSURL *url = [request URL]; + if ([[url scheme] isEqualToString:kCustomProtocolScheme]) { + if ([[url host] isEqualToString:kQueueHasMessage]) { + [self _flushMessageQueue]; + } else { + NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", kCustomProtocolScheme, [url path]); + } + [listener ignore]; + } else if (_webViewDelegate && [_webViewDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:request:frame:decisionListener:)]) { + [_webViewDelegate webView:webView decidePolicyForNavigationAction:actionInformation request:request frame:frame decisionListener:listener]; + } else { + [listener use]; + } +} + +- (void)webView:(WebView *)webView didCommitLoadForFrame:(WebFrame *)frame { + if (webView != _webView) { return; } + + if (_webViewDelegate && [_webViewDelegate respondsToSelector:@selector(webView:didCommitLoadForFrame:)]) { + [_webViewDelegate webView:webView didCommitLoadForFrame:frame]; + } +} + +- (NSURLRequest *)webView:(WebView *)webView resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource { + if (webView != _webView) { return request; } + + if (_webViewDelegate && [_webViewDelegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) { + return [_webViewDelegate webView:webView resource:identifier willSendRequest:request redirectResponse:redirectResponse fromDataSource:dataSource]; + } + + return request; +} + + + +/* Platform specific internals: OSX + **********************************/ +#elif defined WVJB_PLATFORM_IOS + +- (void) _platformSpecificSetup:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { + _messageHandler = messageHandler; + _webView = webView; + _webViewDelegate = webViewDelegate; + _messageHandlers = [NSMutableDictionary dictionary]; + _webView.delegate = self; +} + +- (void) _platformSpecificDealloc { + _webView.delegate = nil; +} + +- (void)webViewDidFinishLoad:(UIWebView *)webView { + if (webView != _webView) { return; } + + _numRequestsLoading--; + + if (_numRequestsLoading == 0 && ![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { + NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; + NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; + [webView stringByEvaluatingJavaScriptFromString:js]; + } + + if (_startupMessageQueue) { + for (id queuedMessage in _startupMessageQueue) { + [self _dispatchMessage:queuedMessage]; + } + _startupMessageQueue = nil; + } + + __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webViewDidFinishLoad:)]) { + [strongDelegate webViewDidFinishLoad:webView]; + } +} + +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { + if (webView != _webView) { return; } + + _numRequestsLoading--; + + __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) { + [strongDelegate webView:webView didFailLoadWithError:error]; + } +} + +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { + if (webView != _webView) { return YES; } + NSURL *url = [request URL]; + __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + if ([[url scheme] isEqualToString:kCustomProtocolScheme]) { + if ([[url host] isEqualToString:kQueueHasMessage]) { + [self _flushMessageQueue]; + } else { + NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", kCustomProtocolScheme, [url path]); + } + return NO; + } else if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) { + return [strongDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType]; + } else { + return YES; + } +} + +- (void)webViewDidStartLoad:(UIWebView *)webView { + if (webView != _webView) { return; } + + _numRequestsLoading++; + + __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webViewDidStartLoad:)]) { + [strongDelegate webViewDidStartLoad:webView]; + } +} + +#endif + +@end diff --git a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h deleted file mode 100644 index 30301c57..00000000 --- a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.h +++ /dev/null @@ -1,48 +0,0 @@ -#define kMessageSeparator @"__WVJB_MESSAGE_SEPERATOR__" -#define kCustomProtocolScheme @"wvjbscheme" -#define kQueueHasMessage @"__WVJB_QUEUE_MESSAGE__" - -#if TARGET_OS_IPHONE && defined(__IPHONE_5_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0) - #define WEAK_FALLBACK weak -#elif TARGET_OS_MAC && defined(__MAC_10_7) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_7) - #define WEAK_FALLBACK weak - #import -#else - #define WEAK_FALLBACK unsafe_unretained -#endif - -typedef void (^WVJBResponseCallback)(id responseData); -typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); - -@interface WebViewJavascriptBridgeAbstract : NSObject - -@property (nonatomic, WEAK_FALLBACK) id webView; -@property (nonatomic, WEAK_FALLBACK) id webViewDelegate; -@property (nonatomic, strong) NSMutableArray *startupMessageQueue; -@property (nonatomic, strong) NSMutableDictionary *responseCallbacks; -@property (nonatomic, strong) NSMutableDictionary *messageHandlers; -@property (atomic, assign) long uniqueId; -@property (nonatomic, copy) WVJBHandler messageHandler; - -+ (void)enableLogging; -- (void)send:(id)message; -- (void)send:(id)message responseCallback:(WVJBResponseCallback)responseCallback; -- (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler; -- (void)callHandler:(NSString*)handlerName; -- (void)callHandler:(NSString*)handlerName data:(id)data; -- (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback; -- (void)reset; - -@end - -@interface WebViewJavascriptBridgeAbstract (Protected) - -- (void)_flushMessageQueue; -- (void)_sendData:(NSDictionary*)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName; -- (void)_queueMessage:(NSDictionary*)message; -- (void)_dispatchMessage:(NSDictionary*)message; -- (NSString*)_serializeMessage:(NSDictionary*)message; -- (NSDictionary*)_deserializeMessageJSON:(NSString*)messageJSON; -- (void)_log:(NSString*)type json:(NSString*)output; - -@end diff --git a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m b/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m deleted file mode 100755 index 98218c31..00000000 --- a/WebViewJavascriptBridgeAbstract/WebViewJavascriptBridgeAbstract.m +++ /dev/null @@ -1,171 +0,0 @@ -#import "WebViewJavascriptBridgeAbstract.h" - -#ifdef USE_JSONKIT - #import "JSONKit.h" -#endif - -@interface WebViewJavascriptBridgeAbstract () - -@end - -@implementation WebViewJavascriptBridgeAbstract - -static bool logging = false; -+ (void)enableLogging { logging = true; } - -- (void)send:(NSDictionary *)data { - [self send:data responseCallback:nil]; -} - -- (void)send:(NSDictionary *)data responseCallback:(WVJBResponseCallback)responseCallback { - [self _sendData:data responseCallback:responseCallback handlerName:nil]; -} - -- (void)callHandler:(NSString *)handlerName { - [self callHandler:handlerName data:nil responseCallback:nil]; -} - -- (void)callHandler:(NSString *)handlerName data:(id)data { - [self callHandler:handlerName data:data responseCallback:nil]; -} - -- (void)callHandler:(NSString *)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback { - [self _sendData:data responseCallback:responseCallback handlerName:handlerName]; -} - -- (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler { - self.messageHandlers[handlerName] = [handler copy]; -} - -- (void)reset { - self.startupMessageQueue = [NSMutableArray array]; - self.responseCallbacks = [NSMutableDictionary dictionary]; - self.uniqueId = 0; -} - -@end - -@implementation WebViewJavascriptBridgeAbstract (Protected) - -- (void)_sendData:(NSDictionary *)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName { - NSMutableDictionary* message = [NSMutableDictionary dictionaryWithObject:data forKey:@"data"]; - - if (responseCallback) { - NSString* callbackId = [NSString stringWithFormat:@"objc_cb_%ld", ++self.uniqueId]; - self.responseCallbacks[callbackId] = [responseCallback copy]; - message[@"callbackId"] = callbackId; - } - - if (handlerName) { - message[@"handlerName"] = handlerName; - } - [self _queueMessage:message]; -} - -- (void)_queueMessage:(NSDictionary *)message { - if (self.startupMessageQueue) { - [self.startupMessageQueue addObject:message]; - } else { - [self _dispatchMessage:message]; - } -} - -- (void)_dispatchMessage:(NSDictionary *)message { - NSString *messageJSON = [self _serializeMessage:message]; - [self _log:@"sending" json:messageJSON]; - messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; - messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; - messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\'" withString:@"\\\'"]; - messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]; - messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r" withString:@"\\r"]; - messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\f" withString:@"\\f"]; - __strong typeof(self.webView) strongWebView = self.webView; - if ([[NSThread currentThread] isMainThread]) { - [strongWebView performSelector:@selector(stringByEvaluatingJavaScriptFromString:) - withObject:[NSString stringWithFormat: - @"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]]; - } else { - dispatch_sync(dispatch_get_main_queue(), ^{ - [strongWebView performSelector:@selector(stringByEvaluatingJavaScriptFromString:) - withObject:[NSString stringWithFormat: - @"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]]; - }); - } -} - -- (void)_flushMessageQueue { - __strong typeof(self.webView) strongWebView = self.webView; - NSString *messageQueueString = [strongWebView performSelector: - @selector(stringByEvaluatingJavaScriptFromString:) withObject:@"WebViewJavascriptBridge._fetchQueue();"]; - - NSArray* messages = [messageQueueString componentsSeparatedByString:kMessageSeparator]; - for (NSString *messageJSON in messages) { - [self _log:@"receivd" json:messageJSON]; - - NSDictionary* message = [self _deserializeMessageJSON:messageJSON]; - - NSString* responseId = message[@"responseId"]; - if (responseId) { - WVJBResponseCallback responseCallback = self.responseCallbacks[responseId]; - responseCallback(message[@"responseData"]); - [self.responseCallbacks removeObjectForKey:responseId]; - } else { - WVJBResponseCallback responseCallback = NULL; - NSString* callbackId = message[@"callbackId"]; - if (callbackId) { - responseCallback = ^(id responseData) { - NSDictionary* msg = @{ @"responseId":callbackId, @"responseData":responseData }; - [self _queueMessage:msg]; - }; - } else { - responseCallback = ^(id ignoreResponseData) { - // Do nothing - }; - } - - WVJBHandler handler; - if (message[@"handlerName"]) { - handler = self.messageHandlers[message[@"handlerName"]]; - if (!handler) { return NSLog(@"WVJB Warning: No handler for %@", message[@"handlerName"]); } - } else { - handler = self.messageHandler; - } - - @try { - NSDictionary* data = message[@"data"]; - if (!data || ((id)data) == [NSNull null]) { data = [NSDictionary dictionary]; } - handler(data, responseCallback); - } - @catch (NSException *exception) { - NSLog(@"WebViewJavascriptBridge: WARNING: objc handler threw. %@ %@", message, exception); - } - } - } -} - -- (NSString *)_serializeMessage:(NSDictionary *)message { -#ifdef USE_JSONKIT - return [message JSONString]; -#else - return [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:message options:0 error:nil] encoding:NSUTF8StringEncoding]; -#endif -} - -- (NSDictionary *)_deserializeMessageJSON:(NSString *)messageJSON { -#ifdef USE_JSONKIT - return [messageJSON objectFromJSONString]; -#else - return [NSJSONSerialization JSONObjectWithData:[messageJSON dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; -#endif -} - -- (void)_log:(NSString *)action json:(NSString *)json { - if (!logging) { return; } - if (json.length > 500) { - NSLog(@"WVJB %@: %@", action, [[json substringToIndex:500] stringByAppendingString:@" [...]"]); - } else { - NSLog(@"WVJB %@: %@", action, json); - } -} - -@end diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptAbstract b/WebViewJavascriptBridge_OSX/WebViewJavascriptAbstract deleted file mode 120000 index 2cb3269a..00000000 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptAbstract +++ /dev/null @@ -1 +0,0 @@ -../WebViewJavascriptBridgeAbstract \ No newline at end of file diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h deleted file mode 100644 index 41e5305e..00000000 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.h +++ /dev/null @@ -1,11 +0,0 @@ -#import "WebViewJavascriptBridgeAbstract.h" - -@interface WebViewJavascriptBridge : WebViewJavascriptBridgeAbstract - -@property (nonatomic, WEAK_FALLBACK) WebView *webView; -@property (nonatomic, WEAK_FALLBACK) id webViewDelegate; - -+ (instancetype)bridgeForWebView:(WebView*)webView handler:(WVJBHandler)handler; -+ (instancetype)bridgeForWebView:(WebView*)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)handler; - -@end diff --git a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m b/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m deleted file mode 100644 index 5a29a0a3..00000000 --- a/WebViewJavascriptBridge_OSX/WebViewJavascriptBridge_OSX.m +++ /dev/null @@ -1,102 +0,0 @@ -#import "WebViewJavascriptBridge_OSX.h" - -@implementation WebViewJavascriptBridge - -+ (instancetype)bridgeForWebView:(WebView *)webView handler:(WVJBHandler)handler { - return [self bridgeForWebView:webView webViewDelegate:nil handler:handler]; -} - -+ (instancetype)bridgeForWebView:(WebView *)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { - WebViewJavascriptBridge* bridge = [[[self class] alloc] init]; - bridge.messageHandler = messageHandler; - bridge.webView = webView; - bridge.webViewDelegate = webViewDelegate; - bridge.messageHandlers = [NSMutableDictionary dictionary]; - [bridge reset]; - - bridge.webView.frameLoadDelegate = bridge; - bridge.webView.resourceLoadDelegate = bridge; - bridge.webView.policyDelegate = bridge; - - return bridge; -} - -- (void)dealloc; -{ - self.webView.frameLoadDelegate = nil; - self.webView.resourceLoadDelegate = nil; - self.webView.policyDelegate = nil; -} - -- (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame -{ - if (webView != self.webView) { return; } - - if (![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { - NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; - NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; - [webView stringByEvaluatingJavaScriptFromString:js]; - } - - if (self.startupMessageQueue) { - for (id queuedMessage in self.startupMessageQueue) { - [self _dispatchMessage:queuedMessage]; - } - self.startupMessageQueue = nil; - } - - __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; - if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)]) { - [strongDelegate webView:webView didFinishLoadForFrame:frame]; - } -} - -- (void)webView:(WebView *)webView didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { - if (webView != self.webView) { return; } - - __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; - if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) { - [strongDelegate webView:strongDelegate didFailLoadWithError:error forFrame:frame]; - } -} - -- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener -{ - if (webView != self.webView) { [listener use]; } - NSURL *url = [request URL]; - __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; - if ([[url scheme] isEqualToString:kCustomProtocolScheme]) { - if ([[url host] isEqualToString:kQueueHasMessage]) { - [self _flushMessageQueue]; - } else { - NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", kCustomProtocolScheme, [url path]); - } - [listener ignore]; - } else if ([webView resourceLoadDelegate] - && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:request:frame:decisionListener:)]) { - [strongDelegate webView:webView decidePolicyForNavigationAction:actionInformation request:request frame:frame decisionListener:listener]; - } else { - [listener use]; - } -} - -- (void)webView:(WebView *)webView didCommitLoadForFrame:(WebFrame *)frame { - if (webView != self.webView) { return; } - __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; - if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didCommitLoadForFrame:)]) { - [strongDelegate webView:webView didCommitLoadForFrame:frame]; - } -} - -- (NSURLRequest *)webView:(WebView *)webView resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource { - if (webView != self.webView) { return request; } - - __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; - if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) { - return [strongDelegate webView:webView resource:identifier willSendRequest:request redirectResponse:redirectResponse fromDataSource:dataSource]; - } - - return request; -} - -@end diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptAbstract b/WebViewJavascriptBridge_iOS/WebViewJavascriptAbstract deleted file mode 120000 index 2cb3269a..00000000 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptAbstract +++ /dev/null @@ -1 +0,0 @@ -../WebViewJavascriptBridgeAbstract \ No newline at end of file diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h deleted file mode 100644 index b4dc7406..00000000 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.h +++ /dev/null @@ -1,12 +0,0 @@ -#import -#import "WebViewJavascriptBridgeAbstract.h" - -@interface WebViewJavascriptBridge : WebViewJavascriptBridgeAbstract - -@property (nonatomic, WEAK_FALLBACK) UIWebView *webView; -@property (nonatomic, WEAK_FALLBACK) id webViewDelegate; - -+ (instancetype)bridgeForWebView:(UIWebView*)webView handler:(WVJBHandler)handler; -+ (instancetype)bridgeForWebView:(UIWebView*)webView webViewDelegate:(id )webViewDelegate handler:(WVJBHandler)handler; - -@end diff --git a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m b/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m deleted file mode 100644 index 59311ffe..00000000 --- a/WebViewJavascriptBridge_iOS/WebViewJavascriptBridge_iOS.m +++ /dev/null @@ -1,99 +0,0 @@ -#import "WebViewJavascriptBridge_iOS.h" - -@interface WebViewJavascriptBridge () - -@property (nonatomic, assign) NSUInteger numRequestsLoading; - -@end - -@implementation WebViewJavascriptBridge - -#pragma mark UIWebViewDelegate - -+ (instancetype)bridgeForWebView:(UIWebView *)webView handler:(WVJBHandler)handler { - return [self bridgeForWebView:webView webViewDelegate:nil handler:handler]; -} - -+ (instancetype)bridgeForWebView:(UIWebView *)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { - WebViewJavascriptBridge* bridge = [[[self class] alloc] init]; - bridge.messageHandler = messageHandler; - bridge.webView = webView; - bridge.webViewDelegate = webViewDelegate; - bridge.messageHandlers = [NSMutableDictionary dictionary]; - [bridge reset]; - - [webView setDelegate:bridge]; - - return bridge; -} - -- (void)dealloc; -{ - self.webView.delegate = nil; -} - -- (void)webViewDidFinishLoad:(UIWebView *)webView { - if (webView != self.webView) { return; } - - self.numRequestsLoading--; - - if (self.numRequestsLoading == 0 && ![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { - NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; - NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; - [webView stringByEvaluatingJavaScriptFromString:js]; - } - - if (self.startupMessageQueue) { - for (id queuedMessage in self.startupMessageQueue) { - [self _dispatchMessage:queuedMessage]; - } - self.startupMessageQueue = nil; - } - - __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; - if (strongDelegate && [strongDelegate respondsToSelector:@selector(webViewDidFinishLoad:)]) { - [strongDelegate webViewDidFinishLoad:webView]; - } -} - -- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { - if (webView != self.webView) { return; } - - self.numRequestsLoading--; - - __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; - if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) { - [strongDelegate webView:webView didFailLoadWithError:error]; - } -} - -- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { - if (webView != self.webView) { return YES; } - NSURL *url = [request URL]; - __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; - if ([[url scheme] isEqualToString:kCustomProtocolScheme]) { - if ([[url host] isEqualToString:kQueueHasMessage]) { - [self _flushMessageQueue]; - } else { - NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", kCustomProtocolScheme, [url path]); - } - return NO; - } else if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) { - return [strongDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType]; - } else { - return YES; - } -} - -- (void)webViewDidStartLoad:(UIWebView *)webView { - if (webView != self.webView) { return; } - - self.numRequestsLoading++; - - __strong typeof(self.webViewDelegate) strongDelegate = self.webViewDelegate; - if (strongDelegate && [strongDelegate respondsToSelector:@selector(webViewDidStartLoad:)]) { - [strongDelegate webViewDidStartLoad:webView]; - } -} - -@end From 254ea00267f8c1e03727885f4e1e0fd5f5c78be8 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 14 Jun 2013 13:17:58 -0700 Subject: [PATCH 039/285] If the webview is not our webview then we should not be making nagivation action decisions for it. --- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 6d67b5d2..710331b4 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -256,7 +256,7 @@ - (void)webView:(WebView *)webView didFailLoadWithError:(NSError *)error forFram - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { - if (webView != _webView) { [listener use]; } + if (webView != _webView) { return; } NSURL *url = [request URL]; if ([[url scheme] isEqualToString:kCustomProtocolScheme]) { From 090fc95e40a01ef392ef1d8e4ff346fce5579eed Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 14 Jun 2013 13:21:46 -0700 Subject: [PATCH 040/285] v4.0.0 --- Changelog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Changelog b/Changelog index 849cadb2..374927ba 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,7 @@ +v4.0.0 ++ Consolidate platform-specific code into a single WebViewJavascriptBridge.m/h using macros (57ee322a4c5310eadd28b28f4d8522cd54123301) ++ Bugfix: Don't make navigation decisions for webviews we don't control (254ea00267f8c1e03727885f4e1e0fd5f5c78be8) + v3.1.0 + Dont inject the WVJB bridge until all requests have finished loading (61b853) + Add podspec file (818d49cfc) From 2b4a68c4188ae4499469f6a6fb194377b3fa010d Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Wed, 19 Jun 2013 14:17:56 -0700 Subject: [PATCH 041/285] Fix #45: Use __has_feature for arc weak support --- WebViewJavascriptBridge/WebViewJavascriptBridge.h | 8 -------- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 11 +++++++++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.h b/WebViewJavascriptBridge/WebViewJavascriptBridge.h index 141cd848..836d0c52 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.h +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.h @@ -12,14 +12,6 @@ #define kCustomProtocolScheme @"wvjbscheme" #define kQueueHasMessage @"__WVJB_QUEUE_MESSAGE__" -#if TARGET_OS_IPHONE && defined(__IPHONE_5_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0) - #define WVJB_WEAK_FALLBACK weak -#elif TARGET_OS_MAC && defined(__MAC_10_7) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_7) - #define WVJB_WEAK_FALLBACK weak -#else - #define WVJB_WEAK_FALLBACK unsafe_unretained -#endif - #if defined __MAC_OS_X_VERSION_MAX_ALLOWED #import #define WVJB_PLATFORM_OSX diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 710331b4..bbd2c760 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -8,9 +8,16 @@ #import "WebViewJavascriptBridge.h" +#if __has_feature(objc_arc_weak) + #define WVJB_WEAK __weak +#else + #define WVJB_WEAK __unsafe_unretained +#endif + + @implementation WebViewJavascriptBridge { - __weak WVJB_WEBVIEW_TYPE* _webView; - __weak id _webViewDelegate; + WVJB_WEAK WVJB_WEBVIEW_TYPE* _webView; + WVJB_WEAK id _webViewDelegate; NSMutableArray* _startupMessageQueue; NSMutableDictionary* _responseCallbacks; NSMutableDictionary* _messageHandlers; From c3503532f6ee364de5915e945f2d9e5d2671959f Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Wed, 19 Jun 2013 14:18:13 -0700 Subject: [PATCH 042/285] Add @wangjinhua to list of contributors --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3a8cec56..6edd5797 100644 --- a/README.md +++ b/README.md @@ -199,3 +199,4 @@ Contributors - [@xzeror](https://github.com/xzeror) - [@kelp404](https://github.com/kelp404) - [@peyton](https://github.com/peyton) Peyton Randolph +- [@wangjinhua](https://github.com/wangjinhua) From 832e1ae2adc5483f6a92612436dbf1201c6e0a36 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Wed, 19 Jun 2013 14:18:32 -0700 Subject: [PATCH 043/285] Ensure that the response callback gets called, even if no handler has been defined --- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index bbd2c760..58ef2e70 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -166,7 +166,10 @@ - (void)_flushMessageQueue { WVJBHandler handler; if (message[@"handlerName"]) { handler = _messageHandlers[message[@"handlerName"]]; - if (!handler) { return NSLog(@"WVJB Warning: No handler for %@", message[@"handlerName"]); } + if (!handler) { + NSLog(@"WVJB Warning: No handler for %@", message[@"handlerName"]); + return responseCallback(@{}); + } } else { handler = _messageHandler; } From d45feacdce95d8d00bfec0fb5c2252b8ade440ba Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Wed, 19 Jun 2013 14:19:38 -0700 Subject: [PATCH 044/285] v4.0.1 --- Changelog | 3 +++ WebViewJavascriptBridge.podspec | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index 374927ba..632f803f 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,6 @@ +v4.0.1 ++ Fix detection of arc_weak support + v4.0.0 + Consolidate platform-specific code into a single WebViewJavascriptBridge.m/h using macros (57ee322a4c5310eadd28b28f4d8522cd54123301) + Bugfix: Don't make navigation decisions for webviews we don't control (254ea00267f8c1e03727885f4e1e0fd5f5c78be8) diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index 2471c7fa..ff4ac0bd 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'WebViewJavascriptBridge' - s.version = '3.1.0' + s.version = '4.0.1' s.summary = 'An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews.' s.homepage = 'http://github.com/marcuswestin/WebViewJavascriptBridge' s.license = { :type => 'MIT', :file => 'LICENSE' } From 3ba0b84cce4d9c910f3c3c75c32ff6b3c0c28fe1 Mon Sep 17 00:00:00 2001 From: jacob berkman Date: Mon, 29 Jul 2013 21:47:10 -0700 Subject: [PATCH 045/285] use [NSNull null] instead of nil when using shorthand -callHandler: Fixes NSInvalidArgumentException: "attempt to insert nil object from objects[0]" --- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 58ef2e70..8f2c4ab0 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -56,7 +56,7 @@ - (void)send:(NSDictionary *)data responseCallback:(WVJBResponseCallback)respons } - (void)callHandler:(NSString *)handlerName { - [self callHandler:handlerName data:nil responseCallback:nil]; + [self callHandler:handlerName data:[NSNull null] responseCallback:nil]; } - (void)callHandler:(NSString *)handlerName data:(id)data { From 9297f5c3db30945c31e1f38adea6dad4446666bd Mon Sep 17 00:00:00 2001 From: jacob berkman Date: Tue, 30 Jul 2013 09:59:23 -0700 Subject: [PATCH 046/285] encode message queue as JSON If JS included the separator as part of its data, the Obj-C side would interpret it incorrectly: WebViewJavascriptBridge.send('Including __WVJB_MESSAGE_SEPERATOR__ in my message is broken.'); Before: WVJB receivd: {"data":"Including WVJB receivd: in my message is broken."} After: WVJB receivd: {"data":"Including __WVJB_MESSAGE_SEPERATOR__ in my message is broken."} --- .../WebViewJavascriptBridge.h | 1 - .../WebViewJavascriptBridge.js.txt | 5 ++-- .../WebViewJavascriptBridge.m | 27 ++++++++++++------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.h b/WebViewJavascriptBridge/WebViewJavascriptBridge.h index 836d0c52..d2d0544b 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.h +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.h @@ -8,7 +8,6 @@ #import -#define kMessageSeparator @"__WVJB_MESSAGE_SEPERATOR__" #define kCustomProtocolScheme @"wvjbscheme" #define kQueueHasMessage @"__WVJB_QUEUE_MESSAGE__" diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt b/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt index 7936c0e8..86303713 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt @@ -5,7 +5,6 @@ var receiveMessageQueue = [] var messageHandlers = {} - var MESSAGE_SEPARATOR = '__WVJB_MESSAGE_SEPERATOR__' var CUSTOM_PROTOCOL_SCHEME = 'wvjbscheme' var QUEUE_HAS_MESSAGE = '__WVJB_QUEUE_MESSAGE__' @@ -46,12 +45,12 @@ responseCallbacks[callbackId] = responseCallback message['callbackId'] = callbackId } - sendMessageQueue.push(JSON.stringify(message)) + sendMessageQueue.push(message) messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE } function _fetchQueue() { - var messageQueueString = sendMessageQueue.join(MESSAGE_SEPARATOR) + var messageQueueString = JSON.stringify(sendMessageQueue) sendMessageQueue = [] return messageQueueString } diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 8f2c4ab0..1e4920a5 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -138,12 +138,18 @@ - (void)_dispatchMessage:(NSDictionary *)message { - (void)_flushMessageQueue { NSString *messageQueueString = [_webView stringByEvaluatingJavaScriptFromString:@"WebViewJavascriptBridge._fetchQueue();"]; - NSArray* messages = [messageQueueString componentsSeparatedByString:kMessageSeparator]; - for (NSString *messageJSON in messages) { - [self _log:@"receivd" json:messageJSON]; - - NSDictionary* message = [self _deserializeMessageJSON:messageJSON]; - + id messages = [self _deserializeMessageJSON:messageQueueString]; + if (![messages isKindOfClass:[NSArray class]]) { + NSLog(@"WebViewJavascriptBridge: WARNING: Invalid %@ received: %@", [messages class], messages); + return; + } + for (NSDictionary *message in messages) { + if (![message isKindOfClass:[NSDictionary class]]) { + NSLog(@"WebViewJavascriptBridge: WARNING: Invalid %@ received: %@", [message class], message); + continue; + } + [self _log:@"receivd" json:message]; + NSString* responseId = message[@"responseId"]; if (responseId) { WVJBResponseCallback responseCallback = _responseCallbacks[responseId]; @@ -202,10 +208,13 @@ - (NSDictionary *)_deserializeMessageJSON:(NSString *)messageJSON { #endif } -- (void)_log:(NSString *)action json:(NSString *)json { +- (void)_log:(NSString *)action json:(id)json { if (!logging) { return; } - if (json.length > 500) { - NSLog(@"WVJB %@: %@", action, [[json substringToIndex:500] stringByAppendingString:@" [...]"]); + if (![json isKindOfClass:[NSString class]]) { + json = [self _serializeMessage:json]; + } + if ([json length] > 500) { + NSLog(@"WVJB %@: %@ [...]", action, [json substringToIndex:500]); } else { NSLog(@"WVJB %@: %@", action, json); } From 1afebc96ccf53b5d0371256bfca828b021f1a56f Mon Sep 17 00:00:00 2001 From: Antoine Lagadec Date: Thu, 5 Sep 2013 14:05:47 +0200 Subject: [PATCH 047/285] Readd MainMenu.xib and change target down to 10.7 --- .../ExampleApp-OSX.xcodeproj/project.pbxproj | 6 + Example Apps/ExampleApp-OSX/MainMenu.xib | 3614 +++++++++++++++++ 2 files changed, 3620 insertions(+) create mode 100644 Example Apps/ExampleApp-OSX/MainMenu.xib diff --git a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj index 18313cd6..1a78a146 100644 --- a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 2C136A5A17642704004C7401 /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A5917642704004C7401 /* ExampleApp.html */; }; 2C1562C5176BA9FF00B4AE50 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2C1562C3176BA9FF00B4AE50 /* WebViewJavascriptBridge.js.txt */; }; 2C1562C6176BA9FF00B4AE50 /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1562C4176BA9FF00B4AE50 /* WebViewJavascriptBridge.m */; }; + 2CF17F5317D8AACF006E828B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CF17F5217D8AACF006E828B /* MainMenu.xib */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -36,6 +37,7 @@ 2C1562C2176BA9FF00B4AE50 /* WebViewJavascriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge.h; sourceTree = ""; }; 2C1562C3176BA9FF00B4AE50 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; 2C1562C4176BA9FF00B4AE50 /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge.m; sourceTree = ""; }; + 2CF17F5217D8AACF006E828B /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -94,6 +96,7 @@ 2C136A3617641106004C7401 /* AppDelegate.h */, 2C136A3717641106004C7401 /* AppDelegate.m */, 2C136A5917642704004C7401 /* ExampleApp.html */, + 2CF17F5217D8AACF006E828B /* MainMenu.xib */, 2C1562C1176BA9FF00B4AE50 /* WebViewJavascriptBridge */, 2C136A2B17641106004C7401 /* Supporting Files */, ); @@ -178,6 +181,7 @@ 2C136A2F17641106004C7401 /* InfoPlist.strings in Resources */, 2C136A3517641106004C7401 /* Credits.rtf in Resources */, 2C136A5A17642704004C7401 /* ExampleApp.html in Resources */, + 2CF17F5317D8AACF006E828B /* MainMenu.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -282,6 +286,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ExampleApp-OSX/ExampleApp-OSX-Prefix.pch"; INFOPLIST_FILE = "ExampleApp-OSX/ExampleApp-OSX-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.7; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -294,6 +299,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ExampleApp-OSX/ExampleApp-OSX-Prefix.pch"; INFOPLIST_FILE = "ExampleApp-OSX/ExampleApp-OSX-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.7; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/Example Apps/ExampleApp-OSX/MainMenu.xib b/Example Apps/ExampleApp-OSX/MainMenu.xib new file mode 100644 index 00000000..b7140d43 --- /dev/null +++ b/Example Apps/ExampleApp-OSX/MainMenu.xib @@ -0,0 +1,3614 @@ + + + + 1070 + 11E53 + 2844 + 1138.47 + 569.00 + + 2844 + 1810 + + + IBNSLayoutConstraint + NSButton + NSButtonCell + NSCustomObject + NSMenu + NSMenuItem + NSView + NSWindowTemplate + WebView + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + + + PluginDependencyRecalculationVersion + + + + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + + + ExampleApp-OSX + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + ExampleApp-OSX + + + + About ExampleApp-OSX + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Preferences… + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + Services + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide ExampleApp-OSX + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit ExampleApp-OSX + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 1048576 + 2147483647 + + + submenuAction: + + File + + + + New + n + 1048576 + 2147483647 + + + + + + Open… + o + 1048576 + 2147483647 + + + + + + Open Recent + + 1048576 + 2147483647 + + + submenuAction: + + Open Recent + + + + Clear Menu + + 1048576 + 2147483647 + + + + + _NSRecentDocumentsMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Close + w + 1048576 + 2147483647 + + + + + + Save… + s + 1048576 + 2147483647 + + + + + + Revert to Saved + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Page Setup... + P + 1179648 + 2147483647 + + + + + + + Print… + p + 1048576 + 2147483647 + + + + + + + + + Edit + + 1048576 + 2147483647 + + + submenuAction: + + Edit + + + + Undo + z + 1048576 + 2147483647 + + + + + + Redo + Z + 1179648 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Cut + x + 1048576 + 2147483647 + + + + + + Copy + c + 1048576 + 2147483647 + + + + + + Paste + v + 1048576 + 2147483647 + + + + + + Paste and Match Style + V + 1572864 + 2147483647 + + + + + + Delete + + 1048576 + 2147483647 + + + + + + Select All + a + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Find + + 1048576 + 2147483647 + + + submenuAction: + + Find + + + + Find… + f + 1048576 + 2147483647 + + + 1 + + + + Find and Replace… + f + 1572864 + 2147483647 + + + 12 + + + + Find Next + g + 1048576 + 2147483647 + + + 2 + + + + Find Previous + G + 1179648 + 2147483647 + + + 3 + + + + Use Selection for Find + e + 1048576 + 2147483647 + + + 7 + + + + Jump to Selection + j + 1048576 + 2147483647 + + + + + + + + + Spelling and Grammar + + 1048576 + 2147483647 + + + submenuAction: + + Spelling and Grammar + + + + Show Spelling and Grammar + : + 1048576 + 2147483647 + + + + + + Check Document Now + ; + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Check Spelling While Typing + + 1048576 + 2147483647 + + + + + + Check Grammar With Spelling + + 1048576 + 2147483647 + + + + + + Correct Spelling Automatically + + 2147483647 + + + + + + + + + Substitutions + + 1048576 + 2147483647 + + + submenuAction: + + Substitutions + + + + Show Substitutions + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Smart Copy/Paste + f + 1048576 + 2147483647 + + + 1 + + + + Smart Quotes + g + 1048576 + 2147483647 + + + 2 + + + + Smart Dashes + + 2147483647 + + + + + + Smart Links + G + 1179648 + 2147483647 + + + 3 + + + + Text Replacement + + 2147483647 + + + + + + + + + Transformations + + 2147483647 + + + submenuAction: + + Transformations + + + + Make Upper Case + + 2147483647 + + + + + + Make Lower Case + + 2147483647 + + + + + + Capitalize + + 2147483647 + + + + + + + + + Speech + + 1048576 + 2147483647 + + + submenuAction: + + Speech + + + + Start Speaking + + 1048576 + 2147483647 + + + + + + Stop Speaking + + 1048576 + 2147483647 + + + + + + + + + + + + Format + + 2147483647 + + + submenuAction: + + Format + + + + Font + + 2147483647 + + + submenuAction: + + Font + + + + Show Fonts + t + 1048576 + 2147483647 + + + + + + Bold + b + 1048576 + 2147483647 + + + 2 + + + + Italic + i + 1048576 + 2147483647 + + + 1 + + + + Underline + u + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Bigger + + + 1048576 + 2147483647 + + + 3 + + + + Smaller + - + 1048576 + 2147483647 + + + 4 + + + + YES + YES + + + 2147483647 + + + + + + Kern + + 2147483647 + + + submenuAction: + + Kern + + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Tighten + + 2147483647 + + + + + + Loosen + + 2147483647 + + + + + + + + + Ligatures + + 2147483647 + + + submenuAction: + + Ligatures + + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Use All + + 2147483647 + + + + + + + + + Baseline + + 2147483647 + + + submenuAction: + + Baseline + + + + Use Default + + 2147483647 + + + + + + Superscript + + 2147483647 + + + + + + Subscript + + 2147483647 + + + + + + Raise + + 2147483647 + + + + + + Lower + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Colors + C + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Copy Style + c + 1572864 + 2147483647 + + + + + + Paste Style + v + 1572864 + 2147483647 + + + + + _NSFontMenu + + + + + Text + + 2147483647 + + + submenuAction: + + Text + + + + Align Left + { + 1048576 + 2147483647 + + + + + + Center + | + 1048576 + 2147483647 + + + + + + Justify + + 2147483647 + + + + + + Align Right + } + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Writing Direction + + 2147483647 + + + submenuAction: + + Writing Direction + + + + YES + Paragraph + + 2147483647 + + + + + + CURlZmF1bHQ + + 2147483647 + + + + + + CUxlZnQgdG8gUmlnaHQ + + 2147483647 + + + + + + CVJpZ2h0IHRvIExlZnQ + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + YES + Selection + + 2147483647 + + + + + + CURlZmF1bHQ + + 2147483647 + + + + + + CUxlZnQgdG8gUmlnaHQ + + 2147483647 + + + + + + CVJpZ2h0IHRvIExlZnQ + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Ruler + + 2147483647 + + + + + + Copy Ruler + c + 1310720 + 2147483647 + + + + + + Paste Ruler + v + 1310720 + 2147483647 + + + + + + + + + + + + View + + 1048576 + 2147483647 + + + submenuAction: + + View + + + + Show Toolbar + t + 1572864 + 2147483647 + + + + + + Customize Toolbar… + + 1048576 + 2147483647 + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + Window + + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 2147483647 + + + submenuAction: + + Help + + + + ExampleApp-OSX Help + ? + 1048576 + 2147483647 + + + + + _NSHelpMenu + + + + _NSMainMenu + + + 15 + 2 + {{335, 390}, {480, 360}} + 1954021376 + ExampleApp-OSX + NSWindow + + + + + 256 + + + + 256 + + Apple HTML pasteboard type + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple URL pasteboard type + Apple Web Archive pasteboard type + NSColor pasteboard type + NSFilenamesPboardType + NSStringPboardType + NeXT RTFD pasteboard type + NeXT Rich Text Format v1.0 pasteboard type + NeXT TIFF v4.0 pasteboard type + WebURLsWithTitlesPboardType + public.png + public.url + public.url-name + + {{0, 37}, {480, 323}} + + + + _NS:9 + + + + + + + + + + + YES + YES + + + + 268 + {{20, 10}, {97, 19}} + + + + _NS:9 + YES + + -2080374784 + 134217728 + Send message + + LucidaGrande + 12 + 16 + + _NS:9 + + -2038153216 + 164 + + + 400 + 75 + + + + + 268 + {{125, 10}, {86, 19}} + + + _NS:9 + YES + + -2080374784 + 134217728 + Call Handler + + _NS:9 + + -2038153216 + 164 + + + 400 + 75 + + + + {480, 360} + + + + + {{0, 0}, {1280, 778}} + {10000000000000, 10000000000000} + YES + + + AppDelegate + + + NSFontManager + + + + 256 + + Apple HTML pasteboard type + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple URL pasteboard type + Apple Web Archive pasteboard type + NSColor pasteboard type + NSFilenamesPboardType + NSStringPboardType + NeXT RTFD pasteboard type + NeXT Rich Text Format v1.0 pasteboard type + NeXT TIFF v4.0 pasteboard type + WebURLsWithTitlesPboardType + public.png + public.url + public.url-name + + {254, 200} + + + + _NS:9 + + + + YES + YES + + + + + + + terminate: + + + + 449 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + delegate + + + + 495 + + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + print: + + + + 86 + + + + runPageLayout: + + + + 87 + + + + clearRecentDocuments: + + + + 127 + + + + performClose: + + + + 193 + + + + toggleContinuousSpellChecking: + + + + 222 + + + + undo: + + + + 223 + + + + copy: + + + + 224 + + + + checkSpelling: + + + + 225 + + + + paste: + + + + 226 + + + + stopSpeaking: + + + + 227 + + + + cut: + + + + 228 + + + + showGuessPanel: + + + + 230 + + + + redo: + + + + 231 + + + + selectAll: + + + + 232 + + + + startSpeaking: + + + + 233 + + + + delete: + + + + 235 + + + + performZoom: + + + + 240 + + + + performFindPanelAction: + + + + 241 + + + + centerSelectionInVisibleArea: + + + + 245 + + + + toggleGrammarChecking: + + + + 347 + + + + toggleSmartInsertDelete: + + + + 355 + + + + toggleAutomaticQuoteSubstitution: + + + + 356 + + + + toggleAutomaticLinkDetection: + + + + 357 + + + + saveDocument: + + + + 362 + + + + revertDocumentToSaved: + + + + 364 + + + + runToolbarCustomizationPalette: + + + + 365 + + + + toggleToolbarShown: + + + + 366 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + newDocument: + + + + 373 + + + + openDocument: + + + + 374 + + + + raiseBaseline: + + + + 426 + + + + lowerBaseline: + + + + 427 + + + + copyFont: + + + + 428 + + + + subscript: + + + + 429 + + + + superscript: + + + + 430 + + + + tightenKerning: + + + + 431 + + + + underline: + + + + 432 + + + + orderFrontColorPanel: + + + + 433 + + + + useAllLigatures: + + + + 434 + + + + loosenKerning: + + + + 435 + + + + pasteFont: + + + + 436 + + + + unscript: + + + + 437 + + + + useStandardKerning: + + + + 438 + + + + useStandardLigatures: + + + + 439 + + + + turnOffLigatures: + + + + 440 + + + + turnOffKerning: + + + + 441 + + + + toggleAutomaticSpellingCorrection: + + + + 456 + + + + orderFrontSubstitutionsPanel: + + + + 458 + + + + toggleAutomaticDashSubstitution: + + + + 461 + + + + toggleAutomaticTextReplacement: + + + + 463 + + + + uppercaseWord: + + + + 464 + + + + capitalizeWord: + + + + 467 + + + + lowercaseWord: + + + + 468 + + + + pasteAsPlainText: + + + + 486 + + + + performFindPanelAction: + + + + 487 + + + + performFindPanelAction: + + + + 488 + + + + performFindPanelAction: + + + + 489 + + + + showHelp: + + + + 493 + + + + alignCenter: + + + + 518 + + + + pasteRuler: + + + + 519 + + + + toggleRuler: + + + + 520 + + + + alignRight: + + + + 521 + + + + copyRuler: + + + + 522 + + + + alignJustified: + + + + 523 + + + + alignLeft: + + + + 524 + + + + makeBaseWritingDirectionNatural: + + + + 525 + + + + makeBaseWritingDirectionLeftToRight: + + + + 526 + + + + makeBaseWritingDirectionRightToLeft: + + + + 527 + + + + makeTextWritingDirectionNatural: + + + + 528 + + + + makeTextWritingDirectionLeftToRight: + + + + 529 + + + + makeTextWritingDirectionRightToLeft: + + + + 530 + + + + performFindPanelAction: + + + + 535 + + + + addFontTrait: + + + + 421 + + + + addFontTrait: + + + + 422 + + + + modifyFont: + + + + 423 + + + + orderFrontFontPanel: + + + + 424 + + + + modifyFont: + + + + 425 + + + + window + + + + 532 + + + + webView + + + + 543 + + + + sendMessage: + + + + 555 + + + + callHandler: + + + + 556 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + + + + + + + + + + + + 19 + + + + + + + + 56 + + + + + + + + 217 + + + + + + + + 83 + + + + + + + + 81 + + + + + + + + + + + + + + + + + 75 + + + + + 78 + + + + + 72 + + + + + 82 + + + + + 124 + + + + + + + + 77 + + + + + 73 + + + + + 79 + + + + + 112 + + + + + 74 + + + + + 125 + + + + + + + + 126 + + + + + 205 + + + + + + + + + + + + + + + + + + + + + + 202 + + + + + 198 + + + + + 207 + + + + + 214 + + + + + 199 + + + + + 203 + + + + + 197 + + + + + 206 + + + + + 215 + + + + + 218 + + + + + + + + 216 + + + + + + + + 200 + + + + + + + + + + + + + 219 + + + + + 201 + + + + + 204 + + + + + 220 + + + + + + + + + + + + + 213 + + + + + 210 + + + + + 221 + + + + + 208 + + + + + 209 + + + + + 57 + + + + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + + + 144 + + + + + 129 + + + + + 143 + + + + + 236 + + + + + 131 + + + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 24 + + + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 295 + + + + + + + + 296 + + + + + + + + + 297 + + + + + 298 + + + + + 211 + + + + + + + + 212 + + + + + + + + + 195 + + + + + 196 + + + + + 346 + + + + + 348 + + + + + + + + 349 + + + + + + + + + + + + + + 350 + + + + + 351 + + + + + 354 + + + + + 371 + + + + + + + + 372 + + + + + 11 + 0 + + 11 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 5 + 0 + + 6 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 3 + 0 + + 4 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + 3 + 0 + + 3 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 8 + 29 + 3 + + + + + + + + + 375 + + + + + + + + 376 + + + + + + + + + 377 + + + + + + + + 388 + + + + + + + + + + + + + + + + + + + + + + + 389 + + + + + 390 + + + + + 391 + + + + + 392 + + + + + 393 + + + + + 394 + + + + + 395 + + + + + 396 + + + + + 397 + + + + + + + + 398 + + + + + + + + 399 + + + + + + + + 400 + + + + + 401 + + + + + 402 + + + + + 403 + + + + + 404 + + + + + 405 + + + + + + + + + + + + 406 + + + + + 407 + + + + + 408 + + + + + 409 + + + + + 410 + + + + + 411 + + + + + + + + + + 412 + + + + + 413 + + + + + 414 + + + + + 415 + + + + + + + + + + + 416 + + + + + 417 + + + + + 418 + + + + + 419 + + + + + 420 + + + + + 450 + + + + + + + + 451 + + + + + + + + + + 452 + + + + + 453 + + + + + 454 + + + + + 457 + + + + + 459 + + + + + 460 + + + + + 462 + + + + + 465 + + + + + 466 + + + + + 485 + + + + + 490 + + + + + + + + 491 + + + + + + + + 492 + + + + + 494 + + + + + 496 + + + + + + + + 497 + + + + + + + + + + + + + + + + + 498 + + + + + 499 + + + + + 500 + + + + + 501 + + + + + 502 + + + + + 503 + + + + + + + + 504 + + + + + 505 + + + + + 506 + + + + + 507 + + + + + 508 + + + + + + + + + + + + + + + + 509 + + + + + 510 + + + + + 511 + + + + + 512 + + + + + 513 + + + + + 514 + + + + + 515 + + + + + 516 + + + + + 517 + + + + + 534 + + + + + 536 + + + + + 8 + 0 + + 0 + 1 + + 323 + + 1000 + + 3 + 9 + 1 + + + + + + 539 + + + + + 540 + + + + + 542 + + + + + 544 + + + + + 545 + + + + + + + + 546 + + + + + 550 + + + + + 551 + + + + + + + + 552 + + + + + 554 + + + + + 557 + + + + + 558 + + + + + 559 + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{380, 496}, {480, 360}} + + + + + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + com.apple.WebKitIBPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + 559 + + + + + AppDelegate + NSObject + + id + id + + + + callHandler: + id + + + sendMessage: + id + + + + WebView + NSWindow + + + + webView + WebView + + + window + NSWindow + + + + IBProjectSource + ./Classes/AppDelegate.h + + + + NSLayoutConstraint + NSObject + + IBProjectSource + ./Classes/NSLayoutConstraint.h + + + + + 0 + IBCocoaFramework + YES + 3 + + {11, 11} + {10, 3} + + YES + + From 1df2260564178ed46becd36420e334d78ff1e14a Mon Sep 17 00:00:00 2001 From: Antoine Lagadec Date: Thu, 5 Sep 2013 16:28:15 +0200 Subject: [PATCH 048/285] OSX - Empty Main Menu layout --- Example Apps/ExampleApp-OSX/MainMenu.xib | 6852 ++++++++++------------ 1 file changed, 3241 insertions(+), 3611 deletions(-) diff --git a/Example Apps/ExampleApp-OSX/MainMenu.xib b/Example Apps/ExampleApp-OSX/MainMenu.xib index b7140d43..7dd49232 100644 --- a/Example Apps/ExampleApp-OSX/MainMenu.xib +++ b/Example Apps/ExampleApp-OSX/MainMenu.xib @@ -1,3614 +1,3244 @@ - - 1070 - 11E53 - 2844 - 1138.47 - 569.00 - - 2844 - 1810 - - - IBNSLayoutConstraint - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSView - NSWindowTemplate - WebView - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - - - PluginDependencyRecalculationVersion - - - - - NSApplication - - - FirstResponder - - - NSApplication - - - AMainMenu - - - - ExampleApp-OSX - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - ExampleApp-OSX - - - - About ExampleApp-OSX - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Preferences… - , - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Services - - 1048576 - 2147483647 - - - submenuAction: - - Services - - _NSServicesMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Hide ExampleApp-OSX - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Quit ExampleApp-OSX - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - File - - 1048576 - 2147483647 - - - submenuAction: - - File - - - - New - n - 1048576 - 2147483647 - - - - - - Open… - o - 1048576 - 2147483647 - - - - - - Open Recent - - 1048576 - 2147483647 - - - submenuAction: - - Open Recent - - - - Clear Menu - - 1048576 - 2147483647 - - - - - _NSRecentDocumentsMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Close - w - 1048576 - 2147483647 - - - - - - Save… - s - 1048576 - 2147483647 - - - - - - Revert to Saved - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Page Setup... - P - 1179648 - 2147483647 - - - - - - - Print… - p - 1048576 - 2147483647 - - - - - - - - - Edit - - 1048576 - 2147483647 - - - submenuAction: - - Edit - - - - Undo - z - 1048576 - 2147483647 - - - - - - Redo - Z - 1179648 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Cut - x - 1048576 - 2147483647 - - - - - - Copy - c - 1048576 - 2147483647 - - - - - - Paste - v - 1048576 - 2147483647 - - - - - - Paste and Match Style - V - 1572864 - 2147483647 - - - - - - Delete - - 1048576 - 2147483647 - - - - - - Select All - a - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Find - - 1048576 - 2147483647 - - - submenuAction: - - Find - - - - Find… - f - 1048576 - 2147483647 - - - 1 - - - - Find and Replace… - f - 1572864 - 2147483647 - - - 12 - - - - Find Next - g - 1048576 - 2147483647 - - - 2 - - - - Find Previous - G - 1179648 - 2147483647 - - - 3 - - - - Use Selection for Find - e - 1048576 - 2147483647 - - - 7 - - - - Jump to Selection - j - 1048576 - 2147483647 - - - - - - - - - Spelling and Grammar - - 1048576 - 2147483647 - - - submenuAction: - - Spelling and Grammar - - - - Show Spelling and Grammar - : - 1048576 - 2147483647 - - - - - - Check Document Now - ; - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Check Spelling While Typing - - 1048576 - 2147483647 - - - - - - Check Grammar With Spelling - - 1048576 - 2147483647 - - - - - - Correct Spelling Automatically - - 2147483647 - - - - - - - - - Substitutions - - 1048576 - 2147483647 - - - submenuAction: - - Substitutions - - - - Show Substitutions - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Smart Copy/Paste - f - 1048576 - 2147483647 - - - 1 - - - - Smart Quotes - g - 1048576 - 2147483647 - - - 2 - - - - Smart Dashes - - 2147483647 - - - - - - Smart Links - G - 1179648 - 2147483647 - - - 3 - - - - Text Replacement - - 2147483647 - - - - - - - - - Transformations - - 2147483647 - - - submenuAction: - - Transformations - - - - Make Upper Case - - 2147483647 - - - - - - Make Lower Case - - 2147483647 - - - - - - Capitalize - - 2147483647 - - - - - - - - - Speech - - 1048576 - 2147483647 - - - submenuAction: - - Speech - - - - Start Speaking - - 1048576 - 2147483647 - - - - - - Stop Speaking - - 1048576 - 2147483647 - - - - - - - - - - - - Format - - 2147483647 - - - submenuAction: - - Format - - - - Font - - 2147483647 - - - submenuAction: - - Font - - - - Show Fonts - t - 1048576 - 2147483647 - - - - - - Bold - b - 1048576 - 2147483647 - - - 2 - - - - Italic - i - 1048576 - 2147483647 - - - 1 - - - - Underline - u - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Bigger - + - 1048576 - 2147483647 - - - 3 - - - - Smaller - - - 1048576 - 2147483647 - - - 4 - - - - YES - YES - - - 2147483647 - - - - - - Kern - - 2147483647 - - - submenuAction: - - Kern - - - - Use Default - - 2147483647 - - - - - - Use None - - 2147483647 - - - - - - Tighten - - 2147483647 - - - - - - Loosen - - 2147483647 - - - - - - - - - Ligatures - - 2147483647 - - - submenuAction: - - Ligatures - - - - Use Default - - 2147483647 - - - - - - Use None - - 2147483647 - - - - - - Use All - - 2147483647 - - - - - - - - - Baseline - - 2147483647 - - - submenuAction: - - Baseline - - - - Use Default - - 2147483647 - - - - - - Superscript - - 2147483647 - - - - - - Subscript - - 2147483647 - - - - - - Raise - - 2147483647 - - - - - - Lower - - 2147483647 - - - - - - - - - YES - YES - - - 2147483647 - - - - - - Show Colors - C - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Copy Style - c - 1572864 - 2147483647 - - - - - - Paste Style - v - 1572864 - 2147483647 - - - - - _NSFontMenu - - - - - Text - - 2147483647 - - - submenuAction: - - Text - - - - Align Left - { - 1048576 - 2147483647 - - - - - - Center - | - 1048576 - 2147483647 - - - - - - Justify - - 2147483647 - - - - - - Align Right - } - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Writing Direction - - 2147483647 - - - submenuAction: - - Writing Direction - - - - YES - Paragraph - - 2147483647 - - - - - - CURlZmF1bHQ - - 2147483647 - - - - - - CUxlZnQgdG8gUmlnaHQ - - 2147483647 - - - - - - CVJpZ2h0IHRvIExlZnQ - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - YES - Selection - - 2147483647 - - - - - - CURlZmF1bHQ - - 2147483647 - - - - - - CUxlZnQgdG8gUmlnaHQ - - 2147483647 - - - - - - CVJpZ2h0IHRvIExlZnQ - - 2147483647 - - - - - - - - - YES - YES - - - 2147483647 - - - - - - Show Ruler - - 2147483647 - - - - - - Copy Ruler - c - 1310720 - 2147483647 - - - - - - Paste Ruler - v - 1310720 - 2147483647 - - - - - - - - - - - - View - - 1048576 - 2147483647 - - - submenuAction: - - View - - - - Show Toolbar - t - 1572864 - 2147483647 - - - - - - Customize Toolbar… - - 1048576 - 2147483647 - - - - - - - - - Window - - 1048576 - 2147483647 - - - submenuAction: - - Window - - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Bring All to Front - - 1048576 - 2147483647 - - - - - _NSWindowsMenu - - - - - Help - - 2147483647 - - - submenuAction: - - Help - - - - ExampleApp-OSX Help - ? - 1048576 - 2147483647 - - - - - _NSHelpMenu - - - - _NSMainMenu - - - 15 - 2 - {{335, 390}, {480, 360}} - 1954021376 - ExampleApp-OSX - NSWindow - - - - - 256 - - - - 256 - - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple URL pasteboard type - Apple Web Archive pasteboard type - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - WebURLsWithTitlesPboardType - public.png - public.url - public.url-name - - {{0, 37}, {480, 323}} - - - - _NS:9 - - - - - - - - - - - YES - YES - - - - 268 - {{20, 10}, {97, 19}} - - - - _NS:9 - YES - - -2080374784 - 134217728 - Send message - - LucidaGrande - 12 - 16 - - _NS:9 - - -2038153216 - 164 - - - 400 - 75 - - - - - 268 - {{125, 10}, {86, 19}} - - - _NS:9 - YES - - -2080374784 - 134217728 - Call Handler - - _NS:9 - - -2038153216 - 164 - - - 400 - 75 - - - - {480, 360} - - - - - {{0, 0}, {1280, 778}} - {10000000000000, 10000000000000} - YES - - - AppDelegate - - - NSFontManager - - - - 256 - - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple URL pasteboard type - Apple Web Archive pasteboard type - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - WebURLsWithTitlesPboardType - public.png - public.url - public.url-name - - {254, 200} - - - - _NS:9 - - - - YES - YES - - - - - - - terminate: - - - - 449 - - - - orderFrontStandardAboutPanel: - - - - 142 - - - - delegate - - - - 495 - - - - performMiniaturize: - - - - 37 - - - - arrangeInFront: - - - - 39 - - - - print: - - - - 86 - - - - runPageLayout: - - - - 87 - - - - clearRecentDocuments: - - - - 127 - - - - performClose: - - - - 193 - - - - toggleContinuousSpellChecking: - - - - 222 - - - - undo: - - - - 223 - - - - copy: - - - - 224 - - - - checkSpelling: - - - - 225 - - - - paste: - - - - 226 - - - - stopSpeaking: - - - - 227 - - - - cut: - - - - 228 - - - - showGuessPanel: - - - - 230 - - - - redo: - - - - 231 - - - - selectAll: - - - - 232 - - - - startSpeaking: - - - - 233 - - - - delete: - - - - 235 - - - - performZoom: - - - - 240 - - - - performFindPanelAction: - - - - 241 - - - - centerSelectionInVisibleArea: - - - - 245 - - - - toggleGrammarChecking: - - - - 347 - - - - toggleSmartInsertDelete: - - - - 355 - - - - toggleAutomaticQuoteSubstitution: - - - - 356 - - - - toggleAutomaticLinkDetection: - - - - 357 - - - - saveDocument: - - - - 362 - - - - revertDocumentToSaved: - - - - 364 - - - - runToolbarCustomizationPalette: - - - - 365 - - - - toggleToolbarShown: - - - - 366 - - - - hide: - - - - 367 - - - - hideOtherApplications: - - - - 368 - - - - unhideAllApplications: - - - - 370 - - - - newDocument: - - - - 373 - - - - openDocument: - - - - 374 - - - - raiseBaseline: - - - - 426 - - - - lowerBaseline: - - - - 427 - - - - copyFont: - - - - 428 - - - - subscript: - - - - 429 - - - - superscript: - - - - 430 - - - - tightenKerning: - - - - 431 - - - - underline: - - - - 432 - - - - orderFrontColorPanel: - - - - 433 - - - - useAllLigatures: - - - - 434 - - - - loosenKerning: - - - - 435 - - - - pasteFont: - - - - 436 - - - - unscript: - - - - 437 - - - - useStandardKerning: - - - - 438 - - - - useStandardLigatures: - - - - 439 - - - - turnOffLigatures: - - - - 440 - - - - turnOffKerning: - - - - 441 - - - - toggleAutomaticSpellingCorrection: - - - - 456 - - - - orderFrontSubstitutionsPanel: - - - - 458 - - - - toggleAutomaticDashSubstitution: - - - - 461 - - - - toggleAutomaticTextReplacement: - - - - 463 - - - - uppercaseWord: - - - - 464 - - - - capitalizeWord: - - - - 467 - - - - lowercaseWord: - - - - 468 - - - - pasteAsPlainText: - - - - 486 - - - - performFindPanelAction: - - - - 487 - - - - performFindPanelAction: - - - - 488 - - - - performFindPanelAction: - - - - 489 - - - - showHelp: - - - - 493 - - - - alignCenter: - - - - 518 - - - - pasteRuler: - - - - 519 - - - - toggleRuler: - - - - 520 - - - - alignRight: - - - - 521 - - - - copyRuler: - - - - 522 - - - - alignJustified: - - - - 523 - - - - alignLeft: - - - - 524 - - - - makeBaseWritingDirectionNatural: - - - - 525 - - - - makeBaseWritingDirectionLeftToRight: - - - - 526 - - - - makeBaseWritingDirectionRightToLeft: - - - - 527 - - - - makeTextWritingDirectionNatural: - - - - 528 - - - - makeTextWritingDirectionLeftToRight: - - - - 529 - - - - makeTextWritingDirectionRightToLeft: - - - - 530 - - - - performFindPanelAction: - - - - 535 - - - - addFontTrait: - - - - 421 - - - - addFontTrait: - - - - 422 - - - - modifyFont: - - - - 423 - - - - orderFrontFontPanel: - - - - 424 - - - - modifyFont: - - - - 425 - - - - window - - - - 532 - - - - webView - - - - 543 - - - - sendMessage: - - - - 555 - - - - callHandler: - - - - 556 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 29 - - - - - - - - - - - - - - 19 - - - - - - - - 56 - - - - - - - - 217 - - - - - - - - 83 - - - - - - - - 81 - - - - - - - - - - - - - - - - - 75 - - - - - 78 - - - - - 72 - - - - - 82 - - - - - 124 - - - - - - - - 77 - - - - - 73 - - - - - 79 - - - - - 112 - - - - - 74 - - - - - 125 - - - - - - - - 126 - - - - - 205 - - - - - - - - - - - - - - - - - - - - - - 202 - - - - - 198 - - - - - 207 - - - - - 214 - - - - - 199 - - - - - 203 - - - - - 197 - - - - - 206 - - - - - 215 - - - - - 218 - - - - - - - - 216 - - - - - - - - 200 - - - - - - - - - - - - - 219 - - - - - 201 - - - - - 204 - - - - - 220 - - - - - - - - - - - - - 213 - - - - - 210 - - - - - 221 - - - - - 208 - - - - - 209 - - - - - 57 - - - - - - - - - - - - - - - - - - 58 - - - - - 134 - - - - - 150 - - - - - 136 - - - - - 144 - - - - - 129 - - - - - 143 - - - - - 236 - - - - - 131 - - - - - - - - 149 - - - - - 145 - - - - - 130 - - - - - 24 - - - - - - - - - - - 92 - - - - - 5 - - - - - 239 - - - - - 23 - - - - - 295 - - - - - - - - 296 - - - - - - - - - 297 - - - - - 298 - - - - - 211 - - - - - - - - 212 - - - - - - - - - 195 - - - - - 196 - - - - - 346 - - - - - 348 - - - - - - - - 349 - - - - - - - - - - - - - - 350 - - - - - 351 - - - - - 354 - - - - - 371 - - - - - - - - 372 - - - - - 11 - 0 - - 11 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - - - - 5 - 0 - - 6 - 1 - - 8 - - 1000 - - 6 - 24 - 3 - - - - 3 - 0 - - 4 - 1 - - 8 - - 1000 - - 6 - 24 - 3 - - - - 5 - 0 - - 5 - 1 - - 20 - - 1000 - - 8 - 29 - 3 - - - - 6 - 0 - - 6 - 1 - - 0.0 - - 1000 - - 8 - 29 - 3 - - - - 3 - 0 - - 3 - 1 - - 0.0 - - 1000 - - 8 - 29 - 3 - - - - 5 - 0 - - 5 - 1 - - 0.0 - - 1000 - - 8 - 29 - 3 - - - - - - - - - 375 - - - - - - - - 376 - - - - - - - - - 377 - - - - - - - - 388 - - - - - - - - - - - - - - - - - - - - - - - 389 - - - - - 390 - - - - - 391 - - - - - 392 - - - - - 393 - - - - - 394 - - - - - 395 - - - - - 396 - - - - - 397 - - - - - - - - 398 - - - - - - - - 399 - - - - - - - - 400 - - - - - 401 - - - - - 402 - - - - - 403 - - - - - 404 - - - - - 405 - - - - - - - - - - - - 406 - - - - - 407 - - - - - 408 - - - - - 409 - - - - - 410 - - - - - 411 - - - - - - - - - - 412 - - - - - 413 - - - - - 414 - - - - - 415 - - - - - - - - - - - 416 - - - - - 417 - - - - - 418 - - - - - 419 - - - - - 420 - - - - - 450 - - - - - - - - 451 - - - - - - - - - - 452 - - - - - 453 - - - - - 454 - - - - - 457 - - - - - 459 - - - - - 460 - - - - - 462 - - - - - 465 - - - - - 466 - - - - - 485 - - - - - 490 - - - - - - - - 491 - - - - - - - - 492 - - - - - 494 - - - - - 496 - - - - - - - - 497 - - - - - - - - - - - - - - - - - 498 - - - - - 499 - - - - - 500 - - - - - 501 - - - - - 502 - - - - - 503 - - - - - - - - 504 - - - - - 505 - - - - - 506 - - - - - 507 - - - - - 508 - - - - - - - - - - - - - - - - 509 - - - - - 510 - - - - - 511 - - - - - 512 - - - - - 513 - - - - - 514 - - - - - 515 - - - - - 516 - - - - - 517 - - - - - 534 - - - - - 536 - - - - - 8 - 0 - - 0 - 1 - - 323 - - 1000 - - 3 - 9 - 1 - - - - - - 539 - - - - - 540 - - - - - 542 - - - - - 544 - - - - - 545 - - - - - - - - 546 - - - - - 550 - - - - - 551 - - - - - - - - 552 - - - - - 554 - - - - - 557 - - - - - 558 - - - - - 559 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{380, 496}, {480, 360}} - - - - - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - com.apple.WebKitIBPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 559 - - - - - AppDelegate - NSObject - - id - id - - - - callHandler: - id - - - sendMessage: - id - - - - WebView - NSWindow - - - - webView - WebView - - - window - NSWindow - - - - IBProjectSource - ./Classes/AppDelegate.h - - - - NSLayoutConstraint - NSObject - - IBProjectSource - ./Classes/NSLayoutConstraint.h - - - - - 0 - IBCocoaFramework - YES - 3 - - {11, 11} - {10, 3} - - YES - + + 1070 + 11E53 + 2844 + 1138.47 + 569.00 + + 2844 + 1810 + + + NSCustomObject + NSMenu + NSMenuItem + NSView + NSWindowTemplate + WebView + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + + + PluginDependencyRecalculationVersion + + + + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + + + ExampleApp-OSX + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + ExampleApp-OSX + + + + About ExampleApp-OSX + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Preferences… + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + Services + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide ExampleApp-OSX + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit ExampleApp-OSX + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 1048576 + 2147483647 + + + submenuAction: + + File + + + + New + n + 1048576 + 2147483647 + + + + + + Open… + o + 1048576 + 2147483647 + + + + + + Open Recent + + 1048576 + 2147483647 + + + submenuAction: + + Open Recent + + + + Clear Menu + + 1048576 + 2147483647 + + + + + _NSRecentDocumentsMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Close + w + 1048576 + 2147483647 + + + + + + Save… + s + 1048576 + 2147483647 + + + + + + Revert to Saved + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Page Setup... + P + 1179648 + 2147483647 + + + + + + + Print… + p + 1048576 + 2147483647 + + + + + + + + + Edit + + 1048576 + 2147483647 + + + submenuAction: + + Edit + + + + Undo + z + 1048576 + 2147483647 + + + + + + Redo + Z + 1179648 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Cut + x + 1048576 + 2147483647 + + + + + + Copy + c + 1048576 + 2147483647 + + + + + + Paste + v + 1048576 + 2147483647 + + + + + + Paste and Match Style + V + 1572864 + 2147483647 + + + + + + Delete + + 1048576 + 2147483647 + + + + + + Select All + a + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Find + + 1048576 + 2147483647 + + + submenuAction: + + Find + + + + Find… + f + 1048576 + 2147483647 + + + 1 + + + + Find and Replace… + f + 1572864 + 2147483647 + + + 12 + + + + Find Next + g + 1048576 + 2147483647 + + + 2 + + + + Find Previous + G + 1179648 + 2147483647 + + + 3 + + + + Use Selection for Find + e + 1048576 + 2147483647 + + + 7 + + + + Jump to Selection + j + 1048576 + 2147483647 + + + + + + + + + Spelling and Grammar + + 1048576 + 2147483647 + + + submenuAction: + + Spelling and Grammar + + + + Show Spelling and Grammar + : + 1048576 + 2147483647 + + + + + + Check Document Now + ; + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Check Spelling While Typing + + 1048576 + 2147483647 + + + + + + Check Grammar With Spelling + + 1048576 + 2147483647 + + + + + + Correct Spelling Automatically + + 2147483647 + + + + + + + + + Substitutions + + 1048576 + 2147483647 + + + submenuAction: + + Substitutions + + + + Show Substitutions + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Smart Copy/Paste + f + 1048576 + 2147483647 + + + 1 + + + + Smart Quotes + g + 1048576 + 2147483647 + + + 2 + + + + Smart Dashes + + 2147483647 + + + + + + Smart Links + G + 1179648 + 2147483647 + + + 3 + + + + Text Replacement + + 2147483647 + + + + + + + + + Transformations + + 2147483647 + + + submenuAction: + + Transformations + + + + Make Upper Case + + 2147483647 + + + + + + Make Lower Case + + 2147483647 + + + + + + Capitalize + + 2147483647 + + + + + + + + + Speech + + 1048576 + 2147483647 + + + submenuAction: + + Speech + + + + Start Speaking + + 1048576 + 2147483647 + + + + + + Stop Speaking + + 1048576 + 2147483647 + + + + + + + + + + + + Format + + 2147483647 + + + submenuAction: + + Format + + + + Font + + 2147483647 + + + submenuAction: + + Font + + + + Show Fonts + t + 1048576 + 2147483647 + + + + + + Bold + b + 1048576 + 2147483647 + + + 2 + + + + Italic + i + 1048576 + 2147483647 + + + 1 + + + + Underline + u + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Bigger + + + 1048576 + 2147483647 + + + 3 + + + + Smaller + - + 1048576 + 2147483647 + + + 4 + + + + YES + YES + + + 2147483647 + + + + + + Kern + + 2147483647 + + + submenuAction: + + Kern + + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Tighten + + 2147483647 + + + + + + Loosen + + 2147483647 + + + + + + + + + Ligatures + + 2147483647 + + + submenuAction: + + Ligatures + + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Use All + + 2147483647 + + + + + + + + + Baseline + + 2147483647 + + + submenuAction: + + Baseline + + + + Use Default + + 2147483647 + + + + + + Superscript + + 2147483647 + + + + + + Subscript + + 2147483647 + + + + + + Raise + + 2147483647 + + + + + + Lower + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Colors + C + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Copy Style + c + 1572864 + 2147483647 + + + + + + Paste Style + v + 1572864 + 2147483647 + + + + + _NSFontMenu + + + + + Text + + 2147483647 + + + submenuAction: + + Text + + + + Align Left + { + 1048576 + 2147483647 + + + + + + Center + | + 1048576 + 2147483647 + + + + + + Justify + + 2147483647 + + + + + + Align Right + } + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Writing Direction + + 2147483647 + + + submenuAction: + + Writing Direction + + + + YES + Paragraph + + 2147483647 + + + + + + CURlZmF1bHQ + + 2147483647 + + + + + + CUxlZnQgdG8gUmlnaHQ + + 2147483647 + + + + + + CVJpZ2h0IHRvIExlZnQ + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + YES + Selection + + 2147483647 + + + + + + CURlZmF1bHQ + + 2147483647 + + + + + + CUxlZnQgdG8gUmlnaHQ + + 2147483647 + + + + + + CVJpZ2h0IHRvIExlZnQ + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Ruler + + 2147483647 + + + + + + Copy Ruler + c + 1310720 + 2147483647 + + + + + + Paste Ruler + v + 1310720 + 2147483647 + + + + + + + + + + + + View + + 1048576 + 2147483647 + + + submenuAction: + + View + + + + Show Toolbar + t + 1572864 + 2147483647 + + + + + + Customize Toolbar… + + 1048576 + 2147483647 + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + Window + + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 2147483647 + + + submenuAction: + + Help + + + + ExampleApp-OSX Help + ? + 1048576 + 2147483647 + + + + + _NSHelpMenu + + + + _NSMainMenu + + + 15 + 2 + {{335, 390}, {480, 360}} + 1954021376 + ExampleApp-OSX + NSWindow + + + + + 256 + {480, 360} + + + + + {{0, 0}, {1280, 778}} + {10000000000000, 10000000000000} + YES + + + AppDelegate + + + NSFontManager + + + + 256 + + Apple HTML pasteboard type + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple URL pasteboard type + Apple Web Archive pasteboard type + NSColor pasteboard type + NSFilenamesPboardType + NSStringPboardType + NeXT RTFD pasteboard type + NeXT Rich Text Format v1.0 pasteboard type + NeXT TIFF v4.0 pasteboard type + WebURLsWithTitlesPboardType + public.png + public.url + public.url-name + + {254, 200} + + + _NS:9 + + + + + + + + + + + YES + YES + + + + + + + terminate: + + + + 449 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + delegate + + + + 495 + + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + print: + + + + 86 + + + + runPageLayout: + + + + 87 + + + + clearRecentDocuments: + + + + 127 + + + + performClose: + + + + 193 + + + + toggleContinuousSpellChecking: + + + + 222 + + + + undo: + + + + 223 + + + + copy: + + + + 224 + + + + checkSpelling: + + + + 225 + + + + paste: + + + + 226 + + + + stopSpeaking: + + + + 227 + + + + cut: + + + + 228 + + + + showGuessPanel: + + + + 230 + + + + redo: + + + + 231 + + + + selectAll: + + + + 232 + + + + startSpeaking: + + + + 233 + + + + delete: + + + + 235 + + + + performZoom: + + + + 240 + + + + performFindPanelAction: + + + + 241 + + + + centerSelectionInVisibleArea: + + + + 245 + + + + toggleGrammarChecking: + + + + 347 + + + + toggleSmartInsertDelete: + + + + 355 + + + + toggleAutomaticQuoteSubstitution: + + + + 356 + + + + toggleAutomaticLinkDetection: + + + + 357 + + + + saveDocument: + + + + 362 + + + + revertDocumentToSaved: + + + + 364 + + + + runToolbarCustomizationPalette: + + + + 365 + + + + toggleToolbarShown: + + + + 366 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + newDocument: + + + + 373 + + + + openDocument: + + + + 374 + + + + raiseBaseline: + + + + 426 + + + + lowerBaseline: + + + + 427 + + + + copyFont: + + + + 428 + + + + subscript: + + + + 429 + + + + superscript: + + + + 430 + + + + tightenKerning: + + + + 431 + + + + underline: + + + + 432 + + + + orderFrontColorPanel: + + + + 433 + + + + useAllLigatures: + + + + 434 + + + + loosenKerning: + + + + 435 + + + + pasteFont: + + + + 436 + + + + unscript: + + + + 437 + + + + useStandardKerning: + + + + 438 + + + + useStandardLigatures: + + + + 439 + + + + turnOffLigatures: + + + + 440 + + + + turnOffKerning: + + + + 441 + + + + toggleAutomaticSpellingCorrection: + + + + 456 + + + + orderFrontSubstitutionsPanel: + + + + 458 + + + + toggleAutomaticDashSubstitution: + + + + 461 + + + + toggleAutomaticTextReplacement: + + + + 463 + + + + uppercaseWord: + + + + 464 + + + + capitalizeWord: + + + + 467 + + + + lowercaseWord: + + + + 468 + + + + pasteAsPlainText: + + + + 486 + + + + performFindPanelAction: + + + + 487 + + + + performFindPanelAction: + + + + 488 + + + + performFindPanelAction: + + + + 489 + + + + showHelp: + + + + 493 + + + + alignCenter: + + + + 518 + + + + pasteRuler: + + + + 519 + + + + toggleRuler: + + + + 520 + + + + alignRight: + + + + 521 + + + + copyRuler: + + + + 522 + + + + alignJustified: + + + + 523 + + + + alignLeft: + + + + 524 + + + + makeBaseWritingDirectionNatural: + + + + 525 + + + + makeBaseWritingDirectionLeftToRight: + + + + 526 + + + + makeBaseWritingDirectionRightToLeft: + + + + 527 + + + + makeTextWritingDirectionNatural: + + + + 528 + + + + makeTextWritingDirectionLeftToRight: + + + + 529 + + + + makeTextWritingDirectionRightToLeft: + + + + 530 + + + + performFindPanelAction: + + + + 535 + + + + addFontTrait: + + + + 421 + + + + addFontTrait: + + + + 422 + + + + modifyFont: + + + + 423 + + + + orderFrontFontPanel: + + + + 424 + + + + modifyFont: + + + + 425 + + + + window + + + + 532 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + + + + + + + + + + + + 19 + + + + + + + + 56 + + + + + + + + 217 + + + + + + + + 83 + + + + + + + + 81 + + + + + + + + + + + + + + + + + 75 + + + + + 78 + + + + + 72 + + + + + 82 + + + + + 124 + + + + + + + + 77 + + + + + 73 + + + + + 79 + + + + + 112 + + + + + 74 + + + + + 125 + + + + + + + + 126 + + + + + 205 + + + + + + + + + + + + + + + + + + + + + + 202 + + + + + 198 + + + + + 207 + + + + + 214 + + + + + 199 + + + + + 203 + + + + + 197 + + + + + 206 + + + + + 215 + + + + + 218 + + + + + + + + 216 + + + + + + + + 200 + + + + + + + + + + + + + 219 + + + + + 201 + + + + + 204 + + + + + 220 + + + + + + + + + + + + + 213 + + + + + 210 + + + + + 221 + + + + + 208 + + + + + 209 + + + + + 57 + + + + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + + + 144 + + + + + 129 + + + + + 143 + + + + + 236 + + + + + 131 + + + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 24 + + + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 295 + + + + + + + + 296 + + + + + + + + + 297 + + + + + 298 + + + + + 211 + + + + + + + + 212 + + + + + + + + + 195 + + + + + 196 + + + + + 346 + + + + + 348 + + + + + + + + 349 + + + + + + + + + + + + + + 350 + + + + + 351 + + + + + 354 + + + + + 375 + + + + + + + + 376 + + + + + + + + + 377 + + + + + + + + 388 + + + + + + + + + + + + + + + + + + + + + + + 389 + + + + + 390 + + + + + 391 + + + + + 392 + + + + + 393 + + + + + 394 + + + + + 395 + + + + + 396 + + + + + 397 + + + + + + + + 398 + + + + + + + + 399 + + + + + + + + 400 + + + + + 401 + + + + + 402 + + + + + 403 + + + + + 404 + + + + + 405 + + + + + + + + + + + + 406 + + + + + 407 + + + + + 408 + + + + + 409 + + + + + 410 + + + + + 411 + + + + + + + + + + 412 + + + + + 413 + + + + + 414 + + + + + 415 + + + + + + + + + + + 416 + + + + + 417 + + + + + 418 + + + + + 419 + + + + + 420 + + + + + 450 + + + + + + + + 451 + + + + + + + + + + 452 + + + + + 453 + + + + + 454 + + + + + 457 + + + + + 459 + + + + + 460 + + + + + 462 + + + + + 465 + + + + + 466 + + + + + 485 + + + + + 490 + + + + + + + + 491 + + + + + + + + 492 + + + + + 494 + + + + + 496 + + + + + + + + 497 + + + + + + + + + + + + + + + + + 498 + + + + + 499 + + + + + 500 + + + + + 501 + + + + + 502 + + + + + 503 + + + + + + + + 504 + + + + + 505 + + + + + 506 + + + + + 507 + + + + + 508 + + + + + + + + + + + + + + + + 509 + + + + + 510 + + + + + 511 + + + + + 512 + + + + + 513 + + + + + 514 + + + + + 515 + + + + + 516 + + + + + 517 + + + + + 534 + + + + + 544 + + + + + 371 + + + + + + + + 372 + + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{380, 496}, {480, 360}} + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + 559 + + + + + AppDelegate + NSObject + + window + NSWindow + + + window + + window + NSWindow + + + + IBProjectSource + ./Classes/AppDelegate.h + + + + + 0 + IBCocoaFramework + YES + 3 + + {11, 11} + {10, 3} + + YES + From 4859217465ebea744698eeaf1eb97a148f4121ea Mon Sep 17 00:00:00 2001 From: Miles Matthias Date: Fri, 13 Sep 2013 21:29:17 -0600 Subject: [PATCH 049/285] Fixed a typo in bridge logging statement. --- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 58ef2e70..28865695 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -140,7 +140,7 @@ - (void)_flushMessageQueue { NSArray* messages = [messageQueueString componentsSeparatedByString:kMessageSeparator]; for (NSString *messageJSON in messages) { - [self _log:@"receivd" json:messageJSON]; + [self _log:@"received" json:messageJSON]; NSDictionary* message = [self _deserializeMessageJSON:messageJSON]; From 2f129dac1a842c80afaf6eecb6923985180d3fd9 Mon Sep 17 00:00:00 2001 From: jacob berkman Date: Fri, 27 Sep 2013 13:41:53 -0700 Subject: [PATCH 050/285] handle nil data in _sendData rather than each callHandler --- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 1e4920a5..a540b0ec 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -56,7 +56,7 @@ - (void)send:(NSDictionary *)data responseCallback:(WVJBResponseCallback)respons } - (void)callHandler:(NSString *)handlerName { - [self callHandler:handlerName data:[NSNull null] responseCallback:nil]; + [self callHandler:handlerName data:nil responseCallback:nil]; } - (void)callHandler:(NSString *)handlerName data:(id)data { @@ -92,6 +92,9 @@ - (void)dealloc { } - (void)_sendData:(NSDictionary *)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName { + if (!data) { + data = (NSDictionary *)[NSNull null]; + } NSMutableDictionary* message = [NSMutableDictionary dictionaryWithObject:data forKey:@"data"]; if (responseCallback) { From e75690e7fbca2439fc2f7a0357cb816e6a6137f5 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 27 Sep 2013 14:46:09 -0700 Subject: [PATCH 051/285] Clean up contributors list by using the github generated lists --- README.md | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 6edd5797..a309e453 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,12 @@ To use a WebViewJavascriptBridge in your own project: }) }, false) +Contributors & Forks +-------------------- +Contributors: https://github.com/marcuswestin/WebViewJavascriptBridge/graphs/contributors + +Forks: https://github.com/marcuswestin/WebViewJavascriptBridge/network/members + API Reference ------------- @@ -185,18 +191,3 @@ iOS4 support (with JSONKit) *Note*: iOS4 support has not yet been tested in v2+. WebViewJavascriptBridge uses `NSJSONSerialization` by default. If you need iOS 4 support then you can use [JSONKit](https://github.com/johnezang/JSONKit/), and add `USE_JSONKIT` to the preprocessor macros for your project. - -Contributors ------------- -- [@marcuswestin](https://github.com/marcuswestin) Marcus Westin (Author) -- [@oakho](https://github.com/oakho) Antoine Lagadec (OS X version) -- [@psineur](https://github.com/psineur) Stepan Generalov -- [@sergiocampama](https://github.com/sergiocampama) Sergio Campamá -- [@stringbean](https://github.com/stringbean) Michael Stringer -- [@tanis2000](https://github.com/tanis2000) Valerio Santinelli -- [@drewburch](https://github.com/drewburch) Andrew Burch -- [@pj4533](https://github.com/pj4533) PJ Gray -- [@xzeror](https://github.com/xzeror) -- [@kelp404](https://github.com/kelp404) -- [@peyton](https://github.com/peyton) Peyton Randolph -- [@wangjinhua](https://github.com/wangjinhua) From 54300126b98bd604015e79ef1db4258cd6b67cf2 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 27 Sep 2013 14:46:15 -0700 Subject: [PATCH 052/285] v4.0.2 --- Changelog | 4 ++++ WebViewJavascriptBridge.podspec | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index 632f803f..656786a5 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,7 @@ +v4.0.2 ++ Fix NSInvalidArgumentException: "attempt to insert nil object" when using shorthand -callHandler: ++ Fix sending messages including __WVJB_MESSAGE_SEPERATOR__ string + v4.0.1 + Fix detection of arc_weak support diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index ff4ac0bd..0f931ba0 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'WebViewJavascriptBridge' - s.version = '4.0.1' + s.version = '4.0.2' s.summary = 'An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews.' s.homepage = 'http://github.com/marcuswestin/WebViewJavascriptBridge' s.license = { :type => 'MIT', :file => 'LICENSE' } From 92f90ab7fedda84621891d2abd777581b16c58d3 Mon Sep 17 00:00:00 2001 From: Miles Matthias Date: Thu, 24 Oct 2013 09:55:37 -0600 Subject: [PATCH 053/285] Added our Imbed repo to list of uses in the wild. See http://dojo4.com/blog/announcing-imbed-the-best-way-to-use-web-content-in-an-i-os-app --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a309e453..3a3bfdc6 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ WebViewJavascriptBridge is used by a range of companies and projects. This list - [Sush.io](http://www.sush.io) - Flutterby Labs - JD Media's [鼎盛中华](https://itunes.apple.com/us/app/ding-sheng-zhong-hua/id537273940?mt=8) +- Dojo4's [Imbed](https://github.com/dojo4/imbed) Setup & Examples (iOS & OSX) ---------------------------- From d66f93e9f4a1d87d44dd949bdf99c68f30cb45a9 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Thu, 24 Oct 2013 15:35:31 -0700 Subject: [PATCH 054/285] Make log prefix capital SEND/RCVD --- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index a540b0ec..e673d73a 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -119,7 +119,7 @@ - (void)_queueMessage:(NSDictionary *)message { - (void)_dispatchMessage:(NSDictionary *)message { NSString *messageJSON = [self _serializeMessage:message]; - [self _log:@"sending" json:messageJSON]; + [self _log:@"SEND" json:messageJSON]; messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\'" withString:@"\\\'"]; @@ -151,7 +151,7 @@ - (void)_flushMessageQueue { NSLog(@"WebViewJavascriptBridge: WARNING: Invalid %@ received: %@", [message class], message); continue; } - [self _log:@"receivd" json:message]; + [self _log:@"RCVD" json:message]; NSString* responseId = message[@"responseId"]; if (responseId) { From a91f2906950aa2612178c0b9a6730839da099eaf Mon Sep 17 00:00:00 2001 From: Bastian Bense Date: Fri, 25 Oct 2013 16:06:10 +0200 Subject: [PATCH 055/285] Fix exception if _sendData is called with data == nil --- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index e673d73a..6935e389 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -95,7 +95,11 @@ - (void)_sendData:(NSDictionary *)data responseCallback:(WVJBResponseCallback)re if (!data) { data = (NSDictionary *)[NSNull null]; } - NSMutableDictionary* message = [NSMutableDictionary dictionaryWithObject:data forKey:@"data"]; + NSMutableDictionary* message = [NSMutableDictionary dictionary]; + + if (data) { + message[@"data"] = data; + } if (responseCallback) { NSString* callbackId = [NSString stringWithFormat:@"objc_cb_%ld", ++_uniqueId]; From dc584db1e5c7958100c324881d96a57178945532 Mon Sep 17 00:00:00 2001 From: Miles Matthias Date: Fri, 25 Oct 2013 14:58:00 -0600 Subject: [PATCH 056/285] Replaced source code link to fancy project page for Imbed. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a3bfdc6..f28c52b3 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ WebViewJavascriptBridge is used by a range of companies and projects. This list - [Sush.io](http://www.sush.io) - Flutterby Labs - JD Media's [鼎盛中华](https://itunes.apple.com/us/app/ding-sheng-zhong-hua/id537273940?mt=8) -- Dojo4's [Imbed](https://github.com/dojo4/imbed) +- Dojo4's [Imbed](http://dojo4.github.io/imbed/) Setup & Examples (iOS & OSX) ---------------------------- From c4cb6ab13c18a96db90906b7ea69b48eaa2ed5d0 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 25 Oct 2013 16:56:32 -0700 Subject: [PATCH 057/285] The declared interface for WVJB expected data to be an `id`. However, the implementation assumed `NSDictionary` in a bunch of places. Furthermore, messages received from JS by ObjC were previously always forced into an `NSDictionary` but javascript did not replace null data packets with `{}`. This patch introduces consistency in all of these cases, assuming data to be `id` everywhere, and never changing the value of data. Drop JSONKit. It's 2013! --- Changelog | 4 ++++ .../WebViewJavascriptBridge.m | 24 +++++-------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/Changelog b/Changelog index 656786a5..101de003 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,7 @@ +v4.1.0 ++ Allow for sending null/nil data packets ++ Drop support for JSONKit + v4.0.2 + Fix NSInvalidArgumentException: "attempt to insert nil object" when using shorthand -callHandler: + Fix sending messages including __WVJB_MESSAGE_SEPERATOR__ string diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 6935e389..fcce490f 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -47,11 +47,11 @@ + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WV return bridge; } -- (void)send:(NSDictionary *)data { +- (void)send:(id)data { [self send:data responseCallback:nil]; } -- (void)send:(NSDictionary *)data responseCallback:(WVJBResponseCallback)responseCallback { +- (void)send:(id)data responseCallback:(WVJBResponseCallback)responseCallback { [self _sendData:data responseCallback:responseCallback handlerName:nil]; } @@ -91,10 +91,7 @@ - (void)dealloc { _messageHandler = nil; } -- (void)_sendData:(NSDictionary *)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName { - if (!data) { - data = (NSDictionary *)[NSNull null]; - } +- (void)_sendData:(id)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName { NSMutableDictionary* message = [NSMutableDictionary dictionary]; if (data) { @@ -188,8 +185,7 @@ - (void)_flushMessageQueue { } @try { - NSDictionary* data = message[@"data"]; - if (!data || ((id)data) == [NSNull null]) { data = [NSDictionary dictionary]; } + id data = message[@"data"]; handler(data, responseCallback); } @catch (NSException *exception) { @@ -199,20 +195,12 @@ - (void)_flushMessageQueue { } } -- (NSString *)_serializeMessage:(NSDictionary *)message { -#if defined _JSONKIT_H_ - return [message JSONString]; -#else +- (NSString *)_serializeMessage:(id)message { return [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:message options:0 error:nil] encoding:NSUTF8StringEncoding]; -#endif } - (NSDictionary *)_deserializeMessageJSON:(NSString *)messageJSON { -#if defined _JSONKIT_H_ - return [messageJSON objectFromJSONString]; -#else - return [NSJSONSerialization JSONObjectWithData:[messageJSON dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; -#endif + return [NSJSONSerialization JSONObjectWithData:[messageJSON dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil]; } - (void)_log:(NSString *)action json:(id)json { From b68bc2680b00e7d10ef282275e2b2bf1e51b8bed Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 25 Oct 2013 17:05:25 -0700 Subject: [PATCH 058/285] Use dictionary literals in example app --- Example Apps/ExampleApp-OSX/AppDelegate.m | 4 ++-- Example Apps/ExampleApp-iOS/ExampleAppDelegate.m | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example Apps/ExampleApp-OSX/AppDelegate.m b/Example Apps/ExampleApp-OSX/AppDelegate.m index d4b230c6..990f9779 100644 --- a/Example Apps/ExampleApp-OSX/AppDelegate.m +++ b/Example Apps/ExampleApp-OSX/AppDelegate.m @@ -38,7 +38,7 @@ - (void)_createBridge { NSLog(@"objc got response! %@", responseData); }]; - [_bridge callHandler:@"testJavascriptHandler" data:[NSDictionary dictionaryWithObject:@"before ready" forKey:@"foo"]]; + [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }]; } - (void)_createObjcButtons { @@ -64,7 +64,7 @@ - (void)_sendMessage { } - (void)_callHandler { - NSDictionary* data = [NSDictionary dictionaryWithObject:@"Hi there, JS!" forKey:@"greetingFromObjC"]; + is data = @{ @"greetingFromObjC": @"Hi there, JS!" }; [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { NSLog(@"testJavascriptHandler responded: %@", response); }]; diff --git a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m index 11c6d310..944e4312 100644 --- a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m +++ b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m @@ -26,7 +26,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( NSLog(@"objc got response! %@", responseData); }]; - [_bridge callHandler:@"testJavascriptHandler" data:[NSDictionary dictionaryWithObject:@"before ready" forKey:@"foo"]]; + [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }]; [self renderButtons:webView]; [self loadExamplePage:webView]; @@ -58,7 +58,7 @@ - (void)sendMessage:(id)sender { } - (void)callHandler:(id)sender { - NSDictionary* data = [NSDictionary dictionaryWithObject:@"Hi there, JS!" forKey:@"greetingFromObjC"]; + id data = @{ @"greetingFromObjC": @"Hi there, JS!" }; [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { NSLog(@"testJavascriptHandler responded: %@", response); }]; From 5069f0849648f848648dfc2ec79b20a653943e54 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 25 Oct 2013 17:07:22 -0700 Subject: [PATCH 059/285] Clean up internal representation of messages with a WVJBMessage typedef --- Changelog | 1 + WebViewJavascriptBridge/WebViewJavascriptBridge.m | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Changelog b/Changelog index 101de003..11ac8e4d 100644 --- a/Changelog +++ b/Changelog @@ -1,6 +1,7 @@ v4.1.0 + Allow for sending null/nil data packets + Drop support for JSONKit ++ Clean up internal represenation of messages v4.0.2 + Fix NSInvalidArgumentException: "attempt to insert nil object" when using shorthand -callHandler: diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index fcce490f..8ee60d17 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -14,6 +14,7 @@ #define WVJB_WEAK __unsafe_unretained #endif +typedef NSDictionary WVJBMessage; @implementation WebViewJavascriptBridge { WVJB_WEAK WVJB_WEBVIEW_TYPE* _webView; @@ -110,7 +111,7 @@ - (void)_sendData:(id)data responseCallback:(WVJBResponseCallback)responseCallba [self _queueMessage:message]; } -- (void)_queueMessage:(NSDictionary *)message { +- (void)_queueMessage:(WVJBMessage*)message { if (_startupMessageQueue) { [_startupMessageQueue addObject:message]; } else { @@ -118,7 +119,7 @@ - (void)_queueMessage:(NSDictionary *)message { } } -- (void)_dispatchMessage:(NSDictionary *)message { +- (void)_dispatchMessage:(WVJBMessage*)message { NSString *messageJSON = [self _serializeMessage:message]; [self _log:@"SEND" json:messageJSON]; messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; @@ -147,8 +148,8 @@ - (void)_flushMessageQueue { NSLog(@"WebViewJavascriptBridge: WARNING: Invalid %@ received: %@", [messages class], messages); return; } - for (NSDictionary *message in messages) { - if (![message isKindOfClass:[NSDictionary class]]) { + for (WVJBMessage* message in messages) { + if (![message isKindOfClass:[WVJBMessage class]]) { NSLog(@"WebViewJavascriptBridge: WARNING: Invalid %@ received: %@", [message class], message); continue; } @@ -164,7 +165,7 @@ - (void)_flushMessageQueue { NSString* callbackId = message[@"callbackId"]; if (callbackId) { responseCallback = ^(id responseData) { - NSDictionary* msg = @{ @"responseId":callbackId, @"responseData":responseData }; + WVJBMessage* msg = @{ @"responseId":callbackId, @"responseData":responseData }; [self _queueMessage:msg]; }; } else { @@ -199,7 +200,7 @@ - (NSString *)_serializeMessage:(id)message { return [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:message options:0 error:nil] encoding:NSUTF8StringEncoding]; } -- (NSDictionary *)_deserializeMessageJSON:(NSString *)messageJSON { +- (NSArray*)_deserializeMessageJSON:(NSString *)messageJSON { return [NSJSONSerialization JSONObjectWithData:[messageJSON dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil]; } From fb46cc066a35ce861f40a530309fa2a3d3bddbe0 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 25 Oct 2013 17:08:01 -0700 Subject: [PATCH 060/285] v4.1.0 --- WebViewJavascriptBridge.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index 0f931ba0..227d89be 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'WebViewJavascriptBridge' - s.version = '4.0.2' + s.version = '4.1.0' s.summary = 'An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews.' s.homepage = 'http://github.com/marcuswestin/WebViewJavascriptBridge' s.license = { :type => 'MIT', :file => 'LICENSE' } From 4d4fc9754a219358e894781a4ef243afe2c72146 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 25 Oct 2013 17:26:18 -0700 Subject: [PATCH 061/285] Update JS initialization snippet. Fix #56 (Thanks @refractalize!). Possibly fixes #52. --- Example Apps/ExampleApp-OSX/AppDelegate.m | 2 +- Example Apps/ExampleApp.html | 17 +++++++++++++---- README.md | 18 +++++++++++++++--- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/Example Apps/ExampleApp-OSX/AppDelegate.m b/Example Apps/ExampleApp-OSX/AppDelegate.m index 990f9779..4e77da67 100644 --- a/Example Apps/ExampleApp-OSX/AppDelegate.m +++ b/Example Apps/ExampleApp-OSX/AppDelegate.m @@ -64,7 +64,7 @@ - (void)_sendMessage { } - (void)_callHandler { - is data = @{ @"greetingFromObjC": @"Hi there, JS!" }; + id data = @{ @"greetingFromObjC": @"Hi there, JS!" }; [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { NSLog(@"testJavascriptHandler responded: %@", response); }]; diff --git a/Example Apps/ExampleApp.html b/Example Apps/ExampleApp.html index 30efb6c8..bf5b7bc7 100644 --- a/Example Apps/ExampleApp.html +++ b/Example Apps/ExampleApp.html @@ -12,9 +12,18 @@

WebViewJavascriptBridge Demo

window.onerror = function(err) { log('window.onerror: ' + err) } - document.addEventListener('WebViewJavascriptBridgeReady', onBridgeReady, false) - function onBridgeReady(event) { - var bridge = event.bridge + + function connectWebViewJavascriptBridge(callback) { + if (window.WebViewJavascriptBridge) { + callback(WebViewJavascriptBridge) + } else { + document.addEventListener('WebViewJavascriptBridgeReady', function() { + callback(WebViewJavascriptBridge) + }, false) + } + } + + connectWebViewJavascriptBridge(function(bridge) { var uniqueId = 1 function log(message, data) { var log = document.getElementById('log') @@ -60,7 +69,7 @@

WebViewJavascriptBridge Demo

log('JS got response', response) }) } - } + })
diff --git a/README.md b/README.md index f28c52b3..ef6eb762 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,20 @@ To use a WebViewJavascriptBridge in your own project: 4) Finally, set up the javascript side: - document.addEventListener('WebViewJavascriptBridgeReady', function onBridgeReady(event) { - var bridge = event.bridge + function connectWebViewJavascriptBridge(callback) { + if (window.WebViewJavascriptBridge) { + callback(WebViewJavascriptBridge) + } else { + document.addEventListener('WebViewJavascriptBridgeReady', function() { + callback(WebViewJavascriptBridge) + }, false) + } + } + + connectWebViewJavascriptBridge(function(bridge) { + + /* Init your app here */ + bridge.init(function(message, responseCallback) { alert('Received message: ' + message) if (responseCallback) { @@ -62,7 +74,7 @@ To use a WebViewJavascriptBridge in your own project: bridge.send('Please respond to this', function responseCallback(responseData) { console.log("Javascript got its response", responseData) }) - }, false) + }) Contributors & Forks -------------------- From 3e8e51bc62cf9c26a903311b3b74d8919d971a81 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 25 Oct 2013 17:28:23 -0700 Subject: [PATCH 062/285] Changelog for upcoming v4.1.1 --- Changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Changelog b/Changelog index 11ac8e4d..45f82014 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,6 @@ +intended v4.1.1 ++ Better JS initialization script (thank @refractalize!) + v4.1.0 + Allow for sending null/nil data packets + Drop support for JSONKit From 197bab4152d8ae6e8adfdd65392655cd17bc73d0 Mon Sep 17 00:00:00 2001 From: Bastian Bense Date: Sat, 26 Oct 2013 11:14:17 +0200 Subject: [PATCH 063/285] Fix resource path in podspec --- WebViewJavascriptBridge.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index 227d89be..f4d86f8b 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.platform = :osx s.ios.source_files = 'WebViewJavascriptBridge/*.{h,m}' s.osx.source_files = 'WebViewJavascriptBridge/*.{h,m}' - s.resource = 'WebViewJavascriptBridgeAbstract/WebViewJavascriptBridge.js.txt' + s.resource = 'WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt' s.ios.framework = 'UIKit' s.osx.framework = 'WebKit' end From 01eb1aa8cb5fab2b4f60ff462e8e55088d9661e8 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Tue, 26 Nov 2013 10:38:33 -0800 Subject: [PATCH 064/285] Migrate to latest XCode-recommended settings --- Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj index b71010e5..7ae53eda 100644 --- a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj @@ -139,7 +139,7 @@ 2CEB3EB21602563600548120 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0450; + LastUpgradeCheck = 0500; ORGANIZATIONNAME = "Marcus Westin"; }; buildConfigurationList = 2CEB3EB51602563600548120 /* Build configuration list for PBXProject "ExampleApp-iOS" */; @@ -220,6 +220,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 6.0; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; From f5b48ee40e1bc92f1df49924e13c6b3b7b96c3fc Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Tue, 26 Nov 2013 10:39:16 -0800 Subject: [PATCH 065/285] Add example for webViewDidStartLoad:/webViewDidFinishLoad: to example app. References GH issue #61 --- Example Apps/ExampleApp-iOS/ExampleAppDelegate.h | 2 +- Example Apps/ExampleApp-iOS/ExampleAppDelegate.m | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h index 5fc2d78b..d85c5e94 100644 --- a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h +++ b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h @@ -1,7 +1,7 @@ #import #import "WebViewJavascriptBridge.h" -@interface ExampleAppDelegate : UIResponder +@interface ExampleAppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) WebViewJavascriptBridge *javascriptBridge; diff --git a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m index 944e4312..a41b51c2 100644 --- a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m +++ b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m @@ -5,6 +5,14 @@ @implementation ExampleAppDelegate @synthesize window = _window; @synthesize javascriptBridge = _bridge; +- (void)webViewDidStartLoad:(UIWebView *)webView { + NSLog(@"webViewDidStartLoad"); +} + +- (void)webViewDidFinishLoad:(UIWebView *)webView { + NSLog(@"webViewDidFinishLoad"); +} + - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; UIWebView* webView = [[UIWebView alloc] initWithFrame:self.window.bounds]; @@ -12,7 +20,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [WebViewJavascriptBridge enableLogging]; - _bridge = [WebViewJavascriptBridge bridgeForWebView:webView handler:^(id data, WVJBResponseCallback responseCallback) { + _bridge = [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"ObjC received message from JS: %@", data); responseCallback(@"Response for message from ObjC"); }]; From cd1b1a71c157bfe59aa839408b5e613b78bfe92c Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 6 Dec 2013 13:26:23 -0800 Subject: [PATCH 066/285] Remove left/right landscape orientation support --- Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist | 2 -- 1 file changed, 2 deletions(-) diff --git a/Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist b/Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist index 2e36c495..81d25998 100644 --- a/Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist +++ b/Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist @@ -31,8 +31,6 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight From 4b95cde27472bc54b36556238561a050f4b94285 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Mon, 13 Jan 2014 15:33:05 -0800 Subject: [PATCH 067/285] Have the example iOS app use a UIViewController instead of adding the webview directly to the app window. Fixes #65 on GH --- .../ExampleApp-iOS.xcodeproj/project.pbxproj | 6 ++ .../ExampleApp-iOS/ExampleAppDelegate.h | 11 +-- .../ExampleApp-iOS/ExampleAppDelegate.m | 72 +-------------- .../ExampleApp-iOS/ExampleAppViewController.h | 13 +++ .../ExampleApp-iOS/ExampleAppViewController.m | 88 +++++++++++++++++++ 5 files changed, 111 insertions(+), 79 deletions(-) create mode 100644 Example Apps/ExampleApp-iOS/ExampleAppViewController.h create mode 100644 Example Apps/ExampleApp-iOS/ExampleAppViewController.m diff --git a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj index 7ae53eda..4834adaf 100644 --- a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 2C1562B5176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2C1562B4176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt */; }; 2C1562C0176BA63500B4AE50 /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */; }; + 2C45CA2C1884AD520002A4E2 /* ExampleAppViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C45CA2B1884AD520002A4E2 /* ExampleAppViewController.m */; }; 2CA045BF17117439006DEE8B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045B717117439006DEE8B /* InfoPlist.strings */; }; 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */; }; 2CA045C317117439006DEE8B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BE17117439006DEE8B /* main.m */; }; @@ -23,6 +24,8 @@ 2C1562A8176B9F6200B4AE50 /* WebViewJavascriptBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge.h; sourceTree = ""; }; 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge.m; sourceTree = ""; }; 2C1562B4176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; + 2C45CA2A1884AD520002A4E2 /* ExampleAppViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExampleAppViewController.h; sourceTree = ""; }; + 2C45CA2B1884AD520002A4E2 /* ExampleAppViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleAppViewController.m; sourceTree = ""; }; 2CA045B817117439006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 2CA045B917117439006DEE8B /* ExampleApp-iOS-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ExampleApp-iOS-Info.plist"; sourceTree = ""; }; 2CA045BA17117439006DEE8B /* ExampleApp-iOS-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ExampleApp-iOS-Prefix.pch"; sourceTree = ""; }; @@ -68,6 +71,8 @@ 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */, 2CA045BC17117439006DEE8B /* ExampleAppDelegate.h */, 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */, + 2C45CA2A1884AD520002A4E2 /* ExampleAppViewController.h */, + 2C45CA2B1884AD520002A4E2 /* ExampleAppViewController.m */, 2C1562A7176B9F5400B4AE50 /* WebViewJavascriptBridge */, 2CA046211711A94E006DEE8B /* Supporting Files */, ); @@ -179,6 +184,7 @@ buildActionMask = 2147483647; files = ( 2C1562C0176BA63500B4AE50 /* WebViewJavascriptBridge.m in Sources */, + 2C45CA2C1884AD520002A4E2 /* ExampleAppViewController.m in Sources */, 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */, 2CA045C317117439006DEE8B /* main.m in Sources */, ); diff --git a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h index d85c5e94..f59015d8 100644 --- a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h +++ b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h @@ -1,12 +1,5 @@ #import -#import "WebViewJavascriptBridge.h" - -@interface ExampleAppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; -@property (strong, nonatomic) WebViewJavascriptBridge *javascriptBridge; - -- (void)renderButtons:(UIWebView*)webView; -- (void)loadExamplePage:(UIWebView*)webView; +@interface ExampleAppDelegate : UIResponder +@property (nonatomic) UIWindow *window; @end diff --git a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m index a41b51c2..72f35ded 100644 --- a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m +++ b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m @@ -1,81 +1,13 @@ #import "ExampleAppDelegate.h" +#import "ExampleAppViewController.h" @implementation ExampleAppDelegate -@synthesize window = _window; -@synthesize javascriptBridge = _bridge; - -- (void)webViewDidStartLoad:(UIWebView *)webView { - NSLog(@"webViewDidStartLoad"); -} - -- (void)webViewDidFinishLoad:(UIWebView *)webView { - NSLog(@"webViewDidFinishLoad"); -} - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - UIWebView* webView = [[UIWebView alloc] initWithFrame:self.window.bounds]; - [self.window addSubview:webView]; - - [WebViewJavascriptBridge enableLogging]; - - _bridge = [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) { - NSLog(@"ObjC received message from JS: %@", data); - responseCallback(@"Response for message from ObjC"); - }]; - - [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { - NSLog(@"testObjcCallback called: %@", data); - responseCallback(@"Response from testObjcCallback"); - }]; - - [_bridge send:@"A string sent from ObjC before Webview has loaded." responseCallback:^(id responseData) { - NSLog(@"objc got response! %@", responseData); - }]; - - [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }]; - - [self renderButtons:webView]; - [self loadExamplePage:webView]; - - [_bridge send:@"A string sent from ObjC after Webview has loaded."]; - + self.window.rootViewController = [ExampleAppViewController new]; [self.window makeKeyAndVisible]; return YES; } -- (void)renderButtons:(UIWebView*)webView { - UIButton *messageButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; - [messageButton setTitle:@"Send message" forState:UIControlStateNormal]; - [messageButton addTarget:self action:@selector(sendMessage:) forControlEvents:UIControlEventTouchUpInside]; - [self.window insertSubview:messageButton aboveSubview:webView]; - messageButton.frame = CGRectMake(20, 414, 130, 45); - - UIButton *callbackButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; - [callbackButton setTitle:@"Call handler" forState:UIControlStateNormal]; - [callbackButton addTarget:self action:@selector(callHandler:) forControlEvents:UIControlEventTouchUpInside]; - [self.window insertSubview:callbackButton aboveSubview:webView]; - callbackButton.frame = CGRectMake(170, 414, 130, 45); -} - -- (void)sendMessage:(id)sender { - [_bridge send:@"A string sent from ObjC to JS" responseCallback:^(id response) { - NSLog(@"sendMessage got response: %@", response); - }]; -} - -- (void)callHandler:(id)sender { - id data = @{ @"greetingFromObjC": @"Hi there, JS!" }; - [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { - NSLog(@"testJavascriptHandler responded: %@", response); - }]; -} - -- (void)loadExamplePage:(UIWebView*)webView { - NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; - NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; - [webView loadHTMLString:appHtml baseURL:nil]; -} - @end diff --git a/Example Apps/ExampleApp-iOS/ExampleAppViewController.h b/Example Apps/ExampleApp-iOS/ExampleAppViewController.h new file mode 100644 index 00000000..d2e25c2d --- /dev/null +++ b/Example Apps/ExampleApp-iOS/ExampleAppViewController.h @@ -0,0 +1,13 @@ +// +// ExampleAppViewController.h +// ExampleApp-iOS +// +// Created by Marcus Westin on 1/13/14. +// Copyright (c) 2014 Marcus Westin. All rights reserved. +// + +#import + +@interface ExampleAppViewController : UINavigationController + +@end diff --git a/Example Apps/ExampleApp-iOS/ExampleAppViewController.m b/Example Apps/ExampleApp-iOS/ExampleAppViewController.m new file mode 100644 index 00000000..b9243d61 --- /dev/null +++ b/Example Apps/ExampleApp-iOS/ExampleAppViewController.m @@ -0,0 +1,88 @@ +// +// ExampleAppViewController.m +// ExampleApp-iOS +// +// Created by Marcus Westin on 1/13/14. +// Copyright (c) 2014 Marcus Westin. All rights reserved. +// + +#import "ExampleAppViewController.h" +#import "WebViewJavascriptBridge.h" + +@interface ExampleAppViewController () +@property WebViewJavascriptBridge* bridge; +@end + +@implementation ExampleAppViewController + +- (void)viewWillAppear:(BOOL)animated { + if (_bridge) { return; } + + UIWebView* webView = [[UIWebView alloc] initWithFrame:self.view.bounds]; + [self.view addSubview:webView]; + + [WebViewJavascriptBridge enableLogging]; + + _bridge = [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"ObjC received message from JS: %@", data); + responseCallback(@"Response for message from ObjC"); + }]; + + [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"testObjcCallback called: %@", data); + responseCallback(@"Response from testObjcCallback"); + }]; + + [_bridge send:@"A string sent from ObjC before Webview has loaded." responseCallback:^(id responseData) { + NSLog(@"objc got response! %@", responseData); + }]; + + [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }]; + + [self renderButtons:webView]; + [self loadExamplePage:webView]; + + [_bridge send:@"A string sent from ObjC after Webview has loaded."]; +} + +- (void)webViewDidStartLoad:(UIWebView *)webView { + NSLog(@"webViewDidStartLoad"); +} + +- (void)webViewDidFinishLoad:(UIWebView *)webView { + NSLog(@"webViewDidFinishLoad"); +} + +- (void)renderButtons:(UIWebView*)webView { + UIButton *messageButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; + [messageButton setTitle:@"Send message" forState:UIControlStateNormal]; + [messageButton addTarget:self action:@selector(sendMessage:) forControlEvents:UIControlEventTouchUpInside]; + [self.view insertSubview:messageButton aboveSubview:webView]; + messageButton.frame = CGRectMake(20, 414, 130, 45); + + UIButton *callbackButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; + [callbackButton setTitle:@"Call handler" forState:UIControlStateNormal]; + [callbackButton addTarget:self action:@selector(callHandler:) forControlEvents:UIControlEventTouchUpInside]; + [self.view insertSubview:callbackButton aboveSubview:webView]; + callbackButton.frame = CGRectMake(170, 414, 130, 45); +} + +- (void)sendMessage:(id)sender { + [_bridge send:@"A string sent from ObjC to JS" responseCallback:^(id response) { + NSLog(@"sendMessage got response: %@", response); + }]; +} + +- (void)callHandler:(id)sender { + id data = @{ @"greetingFromObjC": @"Hi there, JS!" }; + [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { + NSLog(@"testJavascriptHandler responded: %@", response); + }]; +} + +- (void)loadExamplePage:(UIWebView*)webView { + NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; + NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; + [webView loadHTMLString:appHtml baseURL:nil]; +} +@end From bae8975aeb3d769e65f6b662133538cc1defa805 Mon Sep 17 00:00:00 2001 From: Joao Antunes Date: Tue, 4 Feb 2014 19:04:38 +0000 Subject: [PATCH 068/285] Facebook Paper use of the bridge Updated the Readme with Facebook Paper app usage. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ef6eb762..9047233b 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ In the Wild ----------- WebViewJavascriptBridge is used by a range of companies and projects. This list is incomplete, but feel free to add your's and send a PR. +- [Facebook Paper](https://facebook.com/paper) - [Yardsale](https://www.getyardsale.com/) - [EverTrue](http://www.evertrue.com/) - [Game Insight](http://www.game-insight.com/) From 5183c4c848d2f9ce3d575081922ba7123edc2608 Mon Sep 17 00:00:00 2001 From: Kamil Burczyk Date: Sun, 9 Feb 2014 17:07:26 +0100 Subject: [PATCH 069/285] Added possibility to set custom bundle where core bridge.js script is located --- .../WebViewJavascriptBridge.h | 1 + .../WebViewJavascriptBridge.m | 22 ++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.h b/WebViewJavascriptBridge/WebViewJavascriptBridge.h index d2d0544b..baa341c8 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.h +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.h @@ -29,6 +29,7 @@ typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView handler:(WVJBHandler)handler; + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)handler; ++ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)handler resourceBundle:(NSBundle*)bundle; + (void)enableLogging; - (void)send:(id)message; diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 8ee60d17..2473c01e 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -25,6 +25,8 @@ @implementation WebViewJavascriptBridge { long _uniqueId; WVJBHandler _messageHandler; + NSBundle *_resourceBundle; + #if defined WVJB_PLATFORM_IOS NSUInteger _numRequestsLoading; #endif @@ -42,8 +44,13 @@ + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView handler:(WVJBHandle } + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)messageHandler { + return [self bridgeForWebView:webView webViewDelegate:webViewDelegate handler:messageHandler resourceBundle:nil]; +} + ++ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)messageHandler resourceBundle:(NSBundle*)bundle +{ WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; - [bridge _platformSpecificSetup:webView webViewDelegate:webViewDelegate handler:messageHandler]; + [bridge _platformSpecificSetup:webView webViewDelegate:webViewDelegate handler:messageHandler resourceBundle:bundle]; [bridge reset]; return bridge; } @@ -222,7 +229,7 @@ - (void)_log:(NSString *)action json:(id)json { **********************************/ #if defined WVJB_PLATFORM_OSX -- (void) _platformSpecificSetup:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)messageHandler { +- (void) _platformSpecificSetup:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)messageHandler resourceBundle:(NSBundle*)bundle{ _messageHandler = messageHandler; _webView = webView; _webViewDelegate = webViewDelegate; @@ -231,6 +238,8 @@ - (void) _platformSpecificSetup:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJ _webView.frameLoadDelegate = self; _webView.resourceLoadDelegate = self; _webView.policyDelegate = self; + + _resourceBundle = bundle; } - (void) _platformSpecificDealloc { @@ -244,7 +253,8 @@ - (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)frame if (webView != _webView) { return; } if (![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { - NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; + NSBundle *bundle = _resourceBundle ? _resourceBundle : [NSBundle mainBundle]; + NSString *filePath = [bundle pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; [webView stringByEvaluatingJavaScriptFromString:js]; } @@ -312,12 +322,13 @@ - (NSURLRequest *)webView:(WebView *)webView resource:(id)identifier willSendReq **********************************/ #elif defined WVJB_PLATFORM_IOS -- (void) _platformSpecificSetup:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler { +- (void) _platformSpecificSetup:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler resourceBundle:(NSBundle*)bundle{ _messageHandler = messageHandler; _webView = webView; _webViewDelegate = webViewDelegate; _messageHandlers = [NSMutableDictionary dictionary]; _webView.delegate = self; + _resourceBundle = bundle; } - (void) _platformSpecificDealloc { @@ -330,7 +341,8 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView { _numRequestsLoading--; if (_numRequestsLoading == 0 && ![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"]) { - NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; + NSBundle *bundle = _resourceBundle ? _resourceBundle : [NSBundle mainBundle]; + NSString *filePath = [bundle pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; [webView stringByEvaluatingJavaScriptFromString:js]; } From f3e0c6acb031b9479f8f533015b7a06c81b51306 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Mon, 10 Feb 2014 09:41:13 -0800 Subject: [PATCH 070/285] Add Facebook Messenger to products/companies using WVJB. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9047233b..5af2b3ce 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ In the Wild ----------- WebViewJavascriptBridge is used by a range of companies and projects. This list is incomplete, but feel free to add your's and send a PR. +- [Facebook Messenger](https://www.facebook.com/mobile/messenger) - [Facebook Paper](https://facebook.com/paper) - [Yardsale](https://www.getyardsale.com/) - [EverTrue](http://www.evertrue.com/) From 16aa68e271e334c1aaf0424737953a6c83280d28 Mon Sep 17 00:00:00 2001 From: shuizhongyueming Date: Sat, 22 Feb 2014 00:09:26 +0800 Subject: [PATCH 071/285] add a method,make the user can decide whether the request from webview should be load except the WVJB request --- .../WebViewJavascriptBridge.h | 15 +++++++++++++ .../WebViewJavascriptBridge.m | 21 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.h b/WebViewJavascriptBridge/WebViewJavascriptBridge.h index baa341c8..dede2189 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.h +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.h @@ -22,13 +22,28 @@ #define WVJB_WEBVIEW_DELEGATE_TYPE NSObject #endif +@protocol WebViewJavascriptBridgeDelegate + +@optional + +// define a method,make the user decide every request from webview should be load except the WVJB request +-(BOOL) WVJB_webView:(UIWebView *)webView +shouldStartLoadWithRequest:(NSURLRequest *)request + navigationType:(UIWebViewNavigationType)navigationType; + + +@end + typedef void (^WVJBResponseCallback)(id responseData); typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); @interface WebViewJavascriptBridge : WVJB_WEBVIEW_DELEGATE_TYPE +@property (nonatomic,weak) id delegate; + + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView handler:(WVJBHandler)handler; + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)handler; ++ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView WVJBDelegate:(id)delegate handler:(WVJBHandler)handler; + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)handler resourceBundle:(NSBundle*)bundle; + (void)enableLogging; diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 2473c01e..919e119b 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -52,6 +52,15 @@ + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WV WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; [bridge _platformSpecificSetup:webView webViewDelegate:webViewDelegate handler:messageHandler resourceBundle:bundle]; [bridge reset]; + bridge.delegate = nil; + return bridge; +} + ++ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView WVJBDelegate:(id)delegate handler:(WVJBHandler)handler { + WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; + [bridge _platformSpecificSetup:webView webViewDelegate:nil handler:handler]; + [bridge reset]; + bridge.delegate = delegate; return bridge; } @@ -385,7 +394,17 @@ - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *) } else if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) { return [strongDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType]; } else { - return YES; + if(self.delegate){ + if([self.delegate respondsToSelector:@selector(WVJB_webView:shouldStartLoadWithRequest:navigationType:)]){ + return [self.delegate WVJB_webView:webView + shouldStartLoadWithRequest:request + navigationType:navigationType]; + }else{ + return YES; + } + }else{ + return YES; + } } } From 1dc02737d14c75d6d30f2aa792937a4199e04345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BF=9C=E5=B0=98?= Date: Wed, 12 Mar 2014 10:53:59 +0800 Subject: [PATCH 072/285] prevent insert nil into dic --- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 2473c01e..2d707e8a 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -172,6 +172,10 @@ - (void)_flushMessageQueue { NSString* callbackId = message[@"callbackId"]; if (callbackId) { responseCallback = ^(id responseData) { + if (responseData == nil) { + responseData = @{}; + } + WVJBMessage* msg = @{ @"responseId":callbackId, @"responseData":responseData }; [self _queueMessage:msg]; }; From 92d4715ff3f0725a37c91354d576f47771f07935 Mon Sep 17 00:00:00 2001 From: Johan Kanflo Date: Sat, 29 Mar 2014 09:49:00 +0100 Subject: [PATCH 073/285] #74 Not possible to load external javascript in ExampleApp.html --- Example Apps/ExampleApp-iOS/ExampleAppViewController.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Example Apps/ExampleApp-iOS/ExampleAppViewController.m b/Example Apps/ExampleApp-iOS/ExampleAppViewController.m index b9243d61..c81e136a 100644 --- a/Example Apps/ExampleApp-iOS/ExampleAppViewController.m +++ b/Example Apps/ExampleApp-iOS/ExampleAppViewController.m @@ -83,6 +83,7 @@ - (void)callHandler:(id)sender { - (void)loadExamplePage:(UIWebView*)webView { NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; - [webView loadHTMLString:appHtml baseURL:nil]; + NSURL *baseURL = [NSURL fileURLWithPath:htmlPath]; + [webView loadHTMLString:appHtml baseURL:baseURL]; } @end From 4c34caa104e2213928dcbfe862ed2aba1119b89a Mon Sep 17 00:00:00 2001 From: Kamil Burczyk Date: Thu, 3 Apr 2014 14:26:17 +0200 Subject: [PATCH 074/285] Updated Readme with custom bundle example --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 5af2b3ce..5012ff33 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,23 @@ Example: NSLog(@"Current UIWebView page URL is: %@", responseData); }]; +#### Custom bundle +`WebViewJavascriptBridge` requires `WebViewJavascriptBridge.js.txt` file that is injected into web view to create a bridge on JS side. Standard implementation uses `mainBundle` to search for this file. If you e.g. build a static library and you have that file placed somewhere else you can use this method to specify which bundle should be searched for `WebViewJavascriptBridge.js.txt` file: + +##### `[WebViewJavascriptBridge bridgeForWebView:(UIWebView/WebView*)webView webViewDelegate:(UIWebViewDelegate*)webViewDelegate handler:(WVJBHandler)handler resourceBundle:(NSBundle*)bundle` + +Example: + + +``` +[WebViewJavascriptBridge bridgeForWebView:_webView + webViewDelegate:self + handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"Received message from javascript: %@", data); + } + resourceBundle:[NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"ResourcesBundle" withExtension:@"bundle"]] +]; +``` ### Javascript API From 1aa0ecfb83cb97ee5c1efbfa28b2948aa3801069 Mon Sep 17 00:00:00 2001 From: Nolan Waite Date: Wed, 16 Apr 2014 03:16:13 -0300 Subject: [PATCH 075/285] Escape U+2028 and U+2029 when writing JSON as a JavaScript string literal. U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR are also not allowed in a JavaScript string literal. Trying to send a message with either would cause an "unexpected EOF" exception on the JavaScript side. --- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 2473c01e..0f1e314a 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -135,6 +135,8 @@ - (void)_dispatchMessage:(WVJBMessage*)message { messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]; messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r" withString:@"\\r"]; messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\f" withString:@"\\f"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\u2028" withString:@"\\u2028"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\u2029" withString:@"\\u2029"]; NSString* javascriptCommand = [NSString stringWithFormat:@"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]; if ([[NSThread currentThread] isMainThread]) { From b8d5856a758f1b66e2f0e6dcb557ba8542a950be Mon Sep 17 00:00:00 2001 From: Nolan Waite Date: Tue, 15 Apr 2014 23:30:56 -0700 Subject: [PATCH 076/285] Fix little typo in comment --- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 2473c01e..805cbc5c 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -318,7 +318,7 @@ - (NSURLRequest *)webView:(WebView *)webView resource:(id)identifier willSendReq -/* Platform specific internals: OSX +/* Platform specific internals: iOS **********************************/ #elif defined WVJB_PLATFORM_IOS From 18b51d212191d38dd237b47b7ad22d05b0060a25 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Thu, 22 May 2014 19:56:53 +0200 Subject: [PATCH 077/285] Upgrade to latest recommended xcode settings for example OSX project ("Automatically detect target architecture") --- Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj index 1a78a146..0e947166 100644 --- a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj @@ -152,7 +152,7 @@ 2C136A1917641106004C7401 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0460; + LastUpgradeCheck = 0510; ORGANIZATIONNAME = "Marcus Westin"; }; buildConfigurationList = 2C136A1C17641106004C7401 /* Build configuration list for PBXProject "ExampleApp-OSX" */; @@ -224,7 +224,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; @@ -257,7 +256,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; From 6da9284f76e59dcd72ca8dc0878c7f4fa5001484 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Thu, 22 May 2014 20:12:16 +0200 Subject: [PATCH 078/285] Revert "Merge pull request #70 from shuizhongyueming/master" This reverts commit 49579d689e23e7326260f5076764affe8f11c3e2, reversing changes made to 18b51d212191d38dd237b47b7ad22d05b0060a25. The added changes only worked for iOS projects, but broke OSX builds. --- .../WebViewJavascriptBridge.h | 15 ------------- .../WebViewJavascriptBridge.m | 21 +------------------ 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.h b/WebViewJavascriptBridge/WebViewJavascriptBridge.h index dede2189..baa341c8 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.h +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.h @@ -22,28 +22,13 @@ #define WVJB_WEBVIEW_DELEGATE_TYPE NSObject #endif -@protocol WebViewJavascriptBridgeDelegate - -@optional - -// define a method,make the user decide every request from webview should be load except the WVJB request --(BOOL) WVJB_webView:(UIWebView *)webView -shouldStartLoadWithRequest:(NSURLRequest *)request - navigationType:(UIWebViewNavigationType)navigationType; - - -@end - typedef void (^WVJBResponseCallback)(id responseData); typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); @interface WebViewJavascriptBridge : WVJB_WEBVIEW_DELEGATE_TYPE -@property (nonatomic,weak) id delegate; - + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView handler:(WVJBHandler)handler; + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)handler; -+ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView WVJBDelegate:(id)delegate handler:(WVJBHandler)handler; + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate handler:(WVJBHandler)handler resourceBundle:(NSBundle*)bundle; + (void)enableLogging; diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 08a0fb66..4addea33 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -52,15 +52,6 @@ + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WV WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; [bridge _platformSpecificSetup:webView webViewDelegate:webViewDelegate handler:messageHandler resourceBundle:bundle]; [bridge reset]; - bridge.delegate = nil; - return bridge; -} - -+ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView WVJBDelegate:(id)delegate handler:(WVJBHandler)handler { - WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; - [bridge _platformSpecificSetup:webView webViewDelegate:nil handler:handler]; - [bridge reset]; - bridge.delegate = delegate; return bridge; } @@ -396,17 +387,7 @@ - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *) } else if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) { return [strongDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType]; } else { - if(self.delegate){ - if([self.delegate respondsToSelector:@selector(WVJB_webView:shouldStartLoadWithRequest:navigationType:)]){ - return [self.delegate WVJB_webView:webView - shouldStartLoadWithRequest:request - navigationType:navigationType]; - }else{ - return YES; - } - }else{ - return YES; - } + return YES; } } From 8a60345a424a857473acb044ca712e713fb14e25 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 23 May 2014 16:24:06 +0200 Subject: [PATCH 079/285] If a response callback gets called with a `nil` response value, then replace that value with `[NSNull null]` instead of `@{}`. This way the javascript will receive a `null` value instead of `{}`. See gh pr #73 --- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 02ff7b2d..e6584568 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -175,7 +175,7 @@ - (void)_flushMessageQueue { if (callbackId) { responseCallback = ^(id responseData) { if (responseData == nil) { - responseData = @{}; + responseData = [NSNull null]; } WVJBMessage* msg = @{ @"responseId":callbackId, @"responseData":responseData }; From 328f341bbdf27fc9ec4f57d2f28512d950fc6651 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 23 May 2014 16:24:27 +0200 Subject: [PATCH 080/285] Always print the received response value, even if it is null --- Example Apps/ExampleApp.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example Apps/ExampleApp.html b/Example Apps/ExampleApp.html index bf5b7bc7..d31f1fb1 100644 --- a/Example Apps/ExampleApp.html +++ b/Example Apps/ExampleApp.html @@ -29,7 +29,7 @@

WebViewJavascriptBridge Demo

var log = document.getElementById('log') var el = document.createElement('div') el.className = 'logLine' - el.innerHTML = uniqueId++ + '. ' + message + (data ? ':
' + JSON.stringify(data) : '') + el.innerHTML = uniqueId++ + '. ' + message + ':
' + JSON.stringify(data) if (log.children.length) { log.insertBefore(el, log.children[0]) } else { log.appendChild(el) } } From 0c2bf6248a2aa84c435a746b58eb2f02120d3308 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 23 May 2014 16:25:56 +0200 Subject: [PATCH 081/285] Changelog --- Changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog b/Changelog index 45f82014..ce17addf 100644 --- a/Changelog +++ b/Changelog @@ -1,5 +1,6 @@ intended v4.1.1 + Better JS initialization script (thank @refractalize!) ++ When passing nil to an objc response callback, replace it with [NSNull null] (becomes null in js) v4.1.0 + Allow for sending null/nil data packets From dba418a4d5ac40ffc52bba5637c7a23dfb8c64c4 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 23 May 2014 16:26:15 +0200 Subject: [PATCH 082/285] bump copyright date --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 1e732703..c44f4d9a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011-2013 Marcus Westin, Antoine Lagadec +Copyright (c) 2011-2014 Marcus Westin, Antoine Lagadec Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation From da91f9b54c3ae41fd1597f2d2b95bec97ae6295a Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 23 May 2014 16:26:44 +0200 Subject: [PATCH 083/285] v4.1.1 --- Changelog | 2 +- WebViewJavascriptBridge.podspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Changelog b/Changelog index ce17addf..f10fbc74 100644 --- a/Changelog +++ b/Changelog @@ -1,4 +1,4 @@ -intended v4.1.1 +v4.1.1 + Better JS initialization script (thank @refractalize!) + When passing nil to an objc response callback, replace it with [NSNull null] (becomes null in js) diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index f4d86f8b..0b5172b1 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'WebViewJavascriptBridge' - s.version = '4.1.0' + s.version = '4.1.1' s.summary = 'An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews.' s.homepage = 'http://github.com/marcuswestin/WebViewJavascriptBridge' s.license = { :type => 'MIT', :file => 'LICENSE' } From 48f88cf07d4eea63d15676b913d3d768041189c7 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 27 Jun 2014 23:51:03 -0400 Subject: [PATCH 084/285] Ensure that the iframe has a source set before appending it to the DOM. This fixes the problems described in github issue #86, where webViewDidStart/FinishLoad were called twice and isLoading was always true. --- WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt b/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt index 86303713..12a8700e 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.js.txt @@ -14,6 +14,7 @@ function _createQueueReadyIframe(doc) { messagingIframe = doc.createElement('iframe') messagingIframe.style.display = 'none' + messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE doc.documentElement.appendChild(messagingIframe) } From 083e876b25dee2c5d22215f21728f49289721252 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Mon, 30 Jun 2014 14:47:35 -0400 Subject: [PATCH 085/285] v4.1.2 --- Changelog | 3 +++ WebViewJavascriptBridge.podspec | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index f10fbc74..c7ddfdb4 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,6 @@ +v4.1.2 ++ Fix bug: webViewDidStart/FinishLoad were called twice and isLoading was always true (#86) + v4.1.1 + Better JS initialization script (thank @refractalize!) + When passing nil to an objc response callback, replace it with [NSNull null] (becomes null in js) diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index 0b5172b1..ac82c5a5 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'WebViewJavascriptBridge' - s.version = '4.1.1' + s.version = '4.1.2' s.summary = 'An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews.' s.homepage = 'http://github.com/marcuswestin/WebViewJavascriptBridge' s.license = { :type => 'MIT', :file => 'LICENSE' } From 4f05b6d88fab7aae34ea13ec09d28de975051e87 Mon Sep 17 00:00:00 2001 From: Pushpak Rangaiah Date: Wed, 9 Jul 2014 22:04:23 +0530 Subject: [PATCH 086/285] Added tag to PodFile git source path Required for PodFile to pass validation and to push updates. --- WebViewJavascriptBridge.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index ac82c5a5..74a55a8e 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -6,7 +6,7 @@ Pod::Spec.new do |s| s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { 'marcuswestin' => 'marcus.westin@gmail.com' } s.requires_arc = true - s.source = { :git => 'https://github.com/marcuswestin/WebViewJavascriptBridge.git' } + s.source = { :git => 'https://github.com/marcuswestin/WebViewJavascriptBridge.git', :tag => s.version.to_s } s.ios.platform = :ios, '5.0' s.osx.platform = :osx s.ios.source_files = 'WebViewJavascriptBridge/*.{h,m}' From 876a1a2e2162955c1da64f96a788b36fadcc8d53 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Thu, 10 Jul 2014 09:20:57 -0400 Subject: [PATCH 087/285] v4.1.3 --- Changelog | 3 +++ WebViewJavascriptBridge.podspec | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index c7ddfdb4..cf3b7731 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,6 @@ +v4.1.3 ++ Update podspec file with tag + v4.1.2 + Fix bug: webViewDidStart/FinishLoad were called twice and isLoading was always true (#86) diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index 74a55a8e..f3345073 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'WebViewJavascriptBridge' - s.version = '4.1.2' + s.version = '4.1.3' s.summary = 'An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews.' s.homepage = 'http://github.com/marcuswestin/WebViewJavascriptBridge' s.license = { :type => 'MIT', :file => 'LICENSE' } From ddb38a16f0db33ed6d678034d53f0fd2e685c314 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Tue, 15 Jul 2014 22:22:55 -0400 Subject: [PATCH 088/285] Update podspec to make `pod trunk push` work as expected --- WebViewJavascriptBridge.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index f3345073..de25a58a 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -2,11 +2,11 @@ Pod::Spec.new do |s| s.name = 'WebViewJavascriptBridge' s.version = '4.1.3' s.summary = 'An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews.' - s.homepage = 'http://github.com/marcuswestin/WebViewJavascriptBridge' + s.homepage = 'https://github.com/marcuswestin/WebViewJavascriptBridge' s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { 'marcuswestin' => 'marcus.westin@gmail.com' } s.requires_arc = true - s.source = { :git => 'https://github.com/marcuswestin/WebViewJavascriptBridge.git', :tag => s.version.to_s } + s.source = { :git => 'https://github.com/marcuswestin/WebViewJavascriptBridge.git', :tag => 'v'+s.version.to_s } s.ios.platform = :ios, '5.0' s.osx.platform = :osx s.ios.source_files = 'WebViewJavascriptBridge/*.{h,m}' From 5b5a6e81fa97addd1f2c033590fb4856a6092f3a Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Tue, 15 Jul 2014 22:29:02 -0400 Subject: [PATCH 089/285] Annotate Changelog with release checklist --- Changelog | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Changelog b/Changelog index cf3b7731..6b7d8faf 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,18 @@ +WebViewJavascriptBridge Changelog +================================= + +Release Checklist +----------------- +- gitu-update +- Note Changelog +- Bump `WebViewJavascriptBridge.podspec` version "X.Y.Z" +- gitm-commit "vX.Y.Z" +- gitt-tag "vX.Y.Z" +- pod trunk push + +Version History +--------------- + v4.1.3 + Update podspec file with tag From 553c77b43461ea21445c85027cdd9e70320398d5 Mon Sep 17 00:00:00 2001 From: Victor Ilyukevich Date: Thu, 17 Jul 2014 01:05:36 +0300 Subject: [PATCH 090/285] Add CareZone to the list who use the library --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5012ff33..8420c7ec 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ WebViewJavascriptBridge is used by a range of companies and projects. This list - Flutterby Labs - JD Media's [鼎盛中华](https://itunes.apple.com/us/app/ding-sheng-zhong-hua/id537273940?mt=8) - Dojo4's [Imbed](http://dojo4.github.io/imbed/) +- [CareZone](https://carezone.com) Setup & Examples (iOS & OSX) ---------------------------- From 40eda37cff0c96d259e56e8faa7542ab523949c7 Mon Sep 17 00:00:00 2001 From: J Spencer Date: Tue, 22 Jul 2014 16:05:59 -0700 Subject: [PATCH 091/285] Removed extra format specifier --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8420c7ec..f36b17b0 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ To use a WebViewJavascriptBridge in your own project: [bridge send:@"Well hello there"]; [bridge send:[NSDictionary dictionaryWithObject:@"Foo" forKey:@"Bar"]]; [bridge send:@"Give me a response, will you?" responseCallback:^(id responseData) { - NSLog(@"ObjC got its response! %@ %@", responseData); + NSLog(@"ObjC got its response! %@", responseData); }]; 4) Finally, set up the javascript side: From 05891801d46ef5f3c049231c5e050f3fb79c2585 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Fri, 1 Aug 2014 12:15:34 -0400 Subject: [PATCH 092/285] Add button in example app to reload webview, to show that reloading the webview works. (See gh issue #94) --- .../ExampleApp-iOS/ExampleAppViewController.m | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Example Apps/ExampleApp-iOS/ExampleAppViewController.m b/Example Apps/ExampleApp-iOS/ExampleAppViewController.m index c81e136a..3f1f7794 100644 --- a/Example Apps/ExampleApp-iOS/ExampleAppViewController.m +++ b/Example Apps/ExampleApp-iOS/ExampleAppViewController.m @@ -54,17 +54,29 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView { } - (void)renderButtons:(UIWebView*)webView { + UIFont* font = [UIFont fontWithName:@"HelveticaNeue" size:12.0]; + UIButton *messageButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [messageButton setTitle:@"Send message" forState:UIControlStateNormal]; [messageButton addTarget:self action:@selector(sendMessage:) forControlEvents:UIControlEventTouchUpInside]; [self.view insertSubview:messageButton aboveSubview:webView]; - messageButton.frame = CGRectMake(20, 414, 130, 45); - + messageButton.frame = CGRectMake(10, 414, 100, 35); + messageButton.titleLabel.font = font; + messageButton.backgroundColor = [UIColor colorWithWhite:1 alpha:0.75]; + UIButton *callbackButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [callbackButton setTitle:@"Call handler" forState:UIControlStateNormal]; [callbackButton addTarget:self action:@selector(callHandler:) forControlEvents:UIControlEventTouchUpInside]; [self.view insertSubview:callbackButton aboveSubview:webView]; - callbackButton.frame = CGRectMake(170, 414, 130, 45); + callbackButton.frame = CGRectMake(110, 414, 100, 35); + callbackButton.titleLabel.font = font; + + UIButton* reloadButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; + [reloadButton setTitle:@"Reload webview" forState:UIControlStateNormal]; + [reloadButton addTarget:webView action:@selector(reload) forControlEvents:UIControlEventTouchUpInside]; + [self.view insertSubview:reloadButton aboveSubview:webView]; + reloadButton.frame = CGRectMake(210, 414, 100, 35); + reloadButton.titleLabel.font = font; } - (void)sendMessage:(id)sender { From 10a214bcb9f1e844ceda9fd7797cdcc1db9dfbab Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 5 Aug 2014 19:23:06 +0300 Subject: [PATCH 093/285] [Fix] Import for iOS. Important for static libraries that do not import in the Precompiled Header (pch). --- WebViewJavascriptBridge/WebViewJavascriptBridge.h | 1 + 1 file changed, 1 insertion(+) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.h b/WebViewJavascriptBridge/WebViewJavascriptBridge.h index baa341c8..6b0334b1 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.h +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.h @@ -17,6 +17,7 @@ #define WVJB_WEBVIEW_TYPE WebView #define WVJB_WEBVIEW_DELEGATE_TYPE NSObject #elif defined __IPHONE_OS_VERSION_MAX_ALLOWED + #import #define WVJB_PLATFORM_IOS #define WVJB_WEBVIEW_TYPE UIWebView #define WVJB_WEBVIEW_DELEGATE_TYPE NSObject From 68a37a2287e1590a8d7ab25181db8be4021da9a6 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Tue, 5 Aug 2014 19:28:21 +0300 Subject: [PATCH 094/285] [Fix] App crash when no handler (_messageHandler) for message from JS. --- WebViewJavascriptBridge/WebViewJavascriptBridge.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index e6584568..6dac3016 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -196,6 +196,10 @@ - (void)_flushMessageQueue { } } else { handler = _messageHandler; + if (!handler) { + NSLog(@"WVJB Warning: No handler for message from JS: %@", message); + return responseCallback(@{}); + } } @try { From 9294201de4f4a6759a41e3975c18bc6d7f104562 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Wed, 27 Aug 2014 13:05:10 -0400 Subject: [PATCH 095/285] Simplify no-handler case: throw exception any time there is no handler for a message. Similarly, let runtime exceptions inside handlers bubble up and be caught by webkit instead of simply logging them in WVJB. References GH PR #97 --- .../WebViewJavascriptBridge.m | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 6dac3016..388b0494 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -190,25 +190,15 @@ - (void)_flushMessageQueue { WVJBHandler handler; if (message[@"handlerName"]) { handler = _messageHandlers[message[@"handlerName"]]; - if (!handler) { - NSLog(@"WVJB Warning: No handler for %@", message[@"handlerName"]); - return responseCallback(@{}); - } } else { handler = _messageHandler; - if (!handler) { - NSLog(@"WVJB Warning: No handler for message from JS: %@", message); - return responseCallback(@{}); - } } - - @try { - id data = message[@"data"]; - handler(data, responseCallback); - } - @catch (NSException *exception) { - NSLog(@"WebViewJavascriptBridge: WARNING: objc handler threw. %@ %@", message, exception); + + if (!handler) { + [NSException raise:@"WVJBNoHandlerException" format:@"No handler for message from JS: %@", message]; } + + handler(message[@"data"], responseCallback); } } } From 646def3b11c19b943cc716894f1604d357c7ca09 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Wed, 27 Aug 2014 13:07:10 -0400 Subject: [PATCH 096/285] v4.1.4 --- Changelog | 4 ++++ WebViewJavascriptBridge.podspec | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index 6b7d8faf..b19f6cfe 100644 --- a/Changelog +++ b/Changelog @@ -13,6 +13,10 @@ Release Checklist Version History --------------- +v4.1.4 ++ Improve how WVJB handles the case when there is no ObjC handler for a message received from js. ++ If an objc handler throws and exception, let it bubble up to the webkit engine instead of catching it in WVJB. + v4.1.3 + Update podspec file with tag diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index de25a58a..fbb16a8b 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'WebViewJavascriptBridge' - s.version = '4.1.3' + s.version = '4.1.4' s.summary = 'An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews.' s.homepage = 'https://github.com/marcuswestin/WebViewJavascriptBridge' s.license = { :type => 'MIT', :file => 'LICENSE' } From dcecc1186719bd701a753360478c99835026fa2a Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Wed, 27 Aug 2014 13:10:56 -0400 Subject: [PATCH 097/285] Remove WebViewJavascriptBridge `-reset` method. It is unreliable and should not be used. See GH issue #99 --- Changelog | 3 +++ .../WebViewJavascriptBridge.h | 1 - .../WebViewJavascriptBridge.m | 16 +++++++++------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Changelog b/Changelog index b19f6cfe..9553abaf 100644 --- a/Changelog +++ b/Changelog @@ -13,6 +13,9 @@ Release Checklist Version History --------------- +Intended v5.0.0 ++ Removed `WebViewJavascriptBridge -reset`. It should never have been exposed as a public API. + v4.1.4 + Improve how WVJB handles the case when there is no ObjC handler for a message received from js. + If an objc handler throws and exception, let it bubble up to the webkit engine instead of catching it in WVJB. diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.h b/WebViewJavascriptBridge/WebViewJavascriptBridge.h index 6b0334b1..9e90829f 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.h +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.h @@ -39,6 +39,5 @@ typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); - (void)callHandler:(NSString*)handlerName; - (void)callHandler:(NSString*)handlerName data:(id)data; - (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback; -- (void)reset; @end diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 388b0494..04ab38ee 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -51,7 +51,6 @@ + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView webViewDelegate:(WV { WebViewJavascriptBridge* bridge = [[WebViewJavascriptBridge alloc] init]; [bridge _platformSpecificSetup:webView webViewDelegate:webViewDelegate handler:messageHandler resourceBundle:bundle]; - [bridge reset]; return bridge; } @@ -79,15 +78,18 @@ - (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler { _messageHandlers[handlerName] = [handler copy]; } -- (void)reset { - _startupMessageQueue = [NSMutableArray array]; - _responseCallbacks = [NSMutableDictionary dictionary]; - _uniqueId = 0; -} - /* Platform agnostic internals *****************************/ +- (id)init { + if (self = [super init]) { + _startupMessageQueue = [NSMutableArray array]; + _responseCallbacks = [NSMutableDictionary dictionary]; + _uniqueId = 0; + } + return self; +} + - (void)dealloc { [self _platformSpecificDealloc]; From 5f10f81e9436b0e5f8ef399e56085b3f6f958bb7 Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Wed, 27 Aug 2014 13:19:02 -0400 Subject: [PATCH 098/285] Use explicit `WVJB_WEBVIEW_DELEGATE_TYPE` instead of inferred `typeof(_webViewDelegate)`. Should hopefully fix GH issues #81 and #98 --- Changelog | 1 + WebViewJavascriptBridge/WebViewJavascriptBridge.m | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Changelog b/Changelog index 9553abaf..a7fb8544 100644 --- a/Changelog +++ b/Changelog @@ -15,6 +15,7 @@ Version History Intended v5.0.0 + Removed `WebViewJavascriptBridge -reset`. It should never have been exposed as a public API. ++ Fixed compilation in C99 mode v4.1.4 + Improve how WVJB handles the case when there is no ObjC handler for a message received from js. diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 04ab38ee..dff06e62 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -356,7 +356,7 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView { _startupMessageQueue = nil; } - __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + __strong WVJB_WEBVIEW_DELEGATE_TYPE* strongDelegate = _webViewDelegate; if (strongDelegate && [strongDelegate respondsToSelector:@selector(webViewDidFinishLoad:)]) { [strongDelegate webViewDidFinishLoad:webView]; } @@ -367,7 +367,7 @@ - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { _numRequestsLoading--; - __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + __strong WVJB_WEBVIEW_DELEGATE_TYPE* strongDelegate = _webViewDelegate; if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) { [strongDelegate webView:webView didFailLoadWithError:error]; } @@ -376,7 +376,7 @@ - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if (webView != _webView) { return YES; } NSURL *url = [request URL]; - __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + __strong WVJB_WEBVIEW_DELEGATE_TYPE* strongDelegate = _webViewDelegate; if ([[url scheme] isEqualToString:kCustomProtocolScheme]) { if ([[url host] isEqualToString:kQueueHasMessage]) { [self _flushMessageQueue]; @@ -396,7 +396,7 @@ - (void)webViewDidStartLoad:(UIWebView *)webView { _numRequestsLoading++; - __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + __strong WVJB_WEBVIEW_DELEGATE_TYPE* strongDelegate = _webViewDelegate; if (strongDelegate && [strongDelegate respondsToSelector:@selector(webViewDidStartLoad:)]) { [strongDelegate webViewDidStartLoad:webView]; } From f39324d731045a664c90e20926e484b0397e9bbc Mon Sep 17 00:00:00 2001 From: lokimeyburg Date: Tue, 14 Oct 2014 13:51:10 -0700 Subject: [PATCH 099/285] Added the WKWebViewJavascriptBridge class --- .../ExampleApp-iOS.xcodeproj/project.pbxproj | 6 + .../WKWebViewJavascriptBridge.h | 39 +++ .../WKWebViewJavascriptBridge.m | 317 ++++++++++++++++++ 3 files changed, 362 insertions(+) create mode 100644 WebViewJavascriptBridge/WKWebViewJavascriptBridge.h create mode 100644 WebViewJavascriptBridge/WKWebViewJavascriptBridge.m diff --git a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj index 4834adaf..43943042 100644 --- a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 0E8082DB19EDC32300479452 /* WKWebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E8082DA19EDC32300479452 /* WKWebViewJavascriptBridge.m */; }; 2C1562B5176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2C1562B4176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt */; }; 2C1562C0176BA63500B4AE50 /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */; }; 2C45CA2C1884AD520002A4E2 /* ExampleAppViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C45CA2B1884AD520002A4E2 /* ExampleAppViewController.m */; }; @@ -21,6 +22,8 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 0E8082D919EDC32300479452 /* WKWebViewJavascriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKWebViewJavascriptBridge.h; sourceTree = ""; }; + 0E8082DA19EDC32300479452 /* WKWebViewJavascriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WKWebViewJavascriptBridge.m; sourceTree = ""; }; 2C1562A8176B9F6200B4AE50 /* WebViewJavascriptBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge.h; sourceTree = ""; }; 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge.m; sourceTree = ""; }; 2C1562B4176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; @@ -60,6 +63,8 @@ 2C1562B4176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt */, 2C1562A8176B9F6200B4AE50 /* WebViewJavascriptBridge.h */, 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */, + 0E8082D919EDC32300479452 /* WKWebViewJavascriptBridge.h */, + 0E8082DA19EDC32300479452 /* WKWebViewJavascriptBridge.m */, ); name = WebViewJavascriptBridge; path = ../../WebViewJavascriptBridge; @@ -184,6 +189,7 @@ buildActionMask = 2147483647; files = ( 2C1562C0176BA63500B4AE50 /* WebViewJavascriptBridge.m in Sources */, + 0E8082DB19EDC32300479452 /* WKWebViewJavascriptBridge.m in Sources */, 2C45CA2C1884AD520002A4E2 /* ExampleAppViewController.m in Sources */, 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */, 2CA045C317117439006DEE8B /* main.m in Sources */, diff --git a/WebViewJavascriptBridge/WKWebViewJavascriptBridge.h b/WebViewJavascriptBridge/WKWebViewJavascriptBridge.h new file mode 100644 index 00000000..0082a462 --- /dev/null +++ b/WebViewJavascriptBridge/WKWebViewJavascriptBridge.h @@ -0,0 +1,39 @@ +// +// WKWebViewJavascriptBridge.h +// +// Created by Loki Meyburg on 10/15/14. +// Copyright (c) 2014 Loki Meyburg. All rights reserved. +// + +#import + +#define kCustomProtocolScheme @"wvjbscheme" +#define kQueueHasMessage @"__WVJB_QUEUE_MESSAGE__" + + +#if defined(__IPHONE_8_0) + #import + #define WVJB_PLATFORM_IOS +// #define WVJB_WEBVIEW_TYPE WKWebView +// #define WVJB_WEBVIEW_DELEGATE_TYPE NSObject +#endif + +typedef void (^WVJBResponseCallback)(id responseData); +typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); + +@interface WKWebViewJavascriptBridge : NSObject + ++ (instancetype)bridgeForWebView:(WKWebView*)webView handler:(WVJBHandler)handler; ++ (instancetype)bridgeForWebView:(WKWebView*)webView webViewDelegate:(NSObject*)webViewDelegate handler:(WVJBHandler)handler; ++ (instancetype)bridgeForWebView:(WKWebView*)webView webViewDelegate:(NSObject*)webViewDelegate handler:(WVJBHandler)handler resourceBundle:(NSBundle*)bundle; ++ (void)enableLogging; + +- (void)send:(id)message; +- (void)send:(id)message responseCallback:(WVJBResponseCallback)responseCallback; +- (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler; +- (void)callHandler:(NSString*)handlerName; +- (void)callHandler:(NSString*)handlerName data:(id)data; +- (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback; +- (void)reset; + +@end \ No newline at end of file diff --git a/WebViewJavascriptBridge/WKWebViewJavascriptBridge.m b/WebViewJavascriptBridge/WKWebViewJavascriptBridge.m new file mode 100644 index 00000000..3b877912 --- /dev/null +++ b/WebViewJavascriptBridge/WKWebViewJavascriptBridge.m @@ -0,0 +1,317 @@ +// +// WKWebViewJavascriptBridge.m +// +// Created by Loki Meyburg on 10/15/14. +// Copyright (c) 2014 Loki Meyburg. All rights reserved. +// + +#import "WKWebViewJavascriptBridge.h" + +typedef NSDictionary WVJBMessage; + +@implementation WKWebViewJavascriptBridge { + WKWebView* _webView; + id _webViewDelegate; + NSMutableArray* _startupMessageQueue; + NSMutableDictionary* _responseCallbacks; + NSMutableDictionary* _messageHandlers; + long _uniqueId; + WVJBHandler _messageHandler; + NSBundle *_resourceBundle; + NSUInteger _numRequestsLoading; +} + +/* API + *****/ + +static bool logging = false; ++ (void)enableLogging { logging = true; } + ++ (instancetype)bridgeForWebView:(WKWebView*)webView handler:(WVJBHandler)handler { + return [self bridgeForWebView:webView webViewDelegate:nil handler:handler]; +} + ++ (instancetype)bridgeForWebView:(WKWebView*)webView webViewDelegate:(NSObject*)webViewDelegate handler:(WVJBHandler)messageHandler { + return [self bridgeForWebView:webView webViewDelegate:webViewDelegate handler:messageHandler resourceBundle:nil]; +} + ++ (instancetype)bridgeForWebView:(WKWebView*)webView webViewDelegate:(NSObject*)webViewDelegate handler:(WVJBHandler)messageHandler resourceBundle:(NSBundle*)bundle +{ + WKWebViewJavascriptBridge* bridge = [[WKWebViewJavascriptBridge alloc] init]; + [bridge _platformSpecificSetup:webView webViewDelegate:webViewDelegate handler:messageHandler resourceBundle:bundle]; + [bridge reset]; + return bridge; +} + +- (void)send:(id)data { + [self send:data responseCallback:nil]; +} + +- (void)send:(id)data responseCallback:(WVJBResponseCallback)responseCallback { + [self _sendData:data responseCallback:responseCallback handlerName:nil]; +} + +- (void)callHandler:(NSString *)handlerName { + [self callHandler:handlerName data:nil responseCallback:nil]; +} + +- (void)callHandler:(NSString *)handlerName data:(id)data { + [self callHandler:handlerName data:data responseCallback:nil]; +} + +- (void)callHandler:(NSString *)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback { + [self _sendData:data responseCallback:responseCallback handlerName:handlerName]; +} + +- (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler { + _messageHandlers[handlerName] = [handler copy]; +} + +- (void)reset { + _startupMessageQueue = [NSMutableArray array]; + _responseCallbacks = [NSMutableDictionary dictionary]; + _uniqueId = 0; +} + +/* Internals + ***********/ + +- (void)dealloc { + [self _platformSpecificDealloc]; + + _webView = nil; + _webViewDelegate = nil; + _startupMessageQueue = nil; + _responseCallbacks = nil; + _messageHandlers = nil; + _messageHandler = nil; +} + +- (void)_sendData:(id)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName { + NSMutableDictionary* message = [NSMutableDictionary dictionary]; + + if (data) { + message[@"data"] = data; + } + + if (responseCallback) { + NSString* callbackId = [NSString stringWithFormat:@"objc_cb_%ld", ++_uniqueId]; + _responseCallbacks[callbackId] = [responseCallback copy]; + message[@"callbackId"] = callbackId; + } + + if (handlerName) { + message[@"handlerName"] = handlerName; + } + [self _queueMessage:message]; +} + +- (void)_queueMessage:(WVJBMessage*)message { + if (_startupMessageQueue) { + [_startupMessageQueue addObject:message]; + } else { + [self _dispatchMessage:message]; + } +} + +- (void)_dispatchMessage:(WVJBMessage*)message { + NSString *messageJSON = [self _serializeMessage:message]; + [self _log:@"SEND" json:messageJSON]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\'" withString:@"\\\'"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r" withString:@"\\r"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\f" withString:@"\\f"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\u2028" withString:@"\\u2028"]; + messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\u2029" withString:@"\\u2029"]; + + NSString* javascriptCommand = [NSString stringWithFormat:@"WebViewJavascriptBridge._handleMessageFromObjC('%@');", messageJSON]; + if ([[NSThread currentThread] isMainThread]) { + [_webView evaluateJavaScript:javascriptCommand completionHandler:nil]; + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ + [_webView evaluateJavaScript:javascriptCommand completionHandler:nil]; + }); + } +} + +- (void)_flushMessageQueue:(NSString *)messageQueueString{ + id messages = [self _deserializeMessageJSON:messageQueueString]; + if (![messages isKindOfClass:[NSArray class]]) { + NSLog(@"WKWebViewJavascriptBridge: WARNING: Invalid %@ received: %@", [messages class], messages); + return; + } + for (WVJBMessage* message in messages) { + if (![message isKindOfClass:[WVJBMessage class]]) { + NSLog(@"WKWebViewJavascriptBridge: WARNING: Invalid %@ received: %@", [message class], message); + continue; + } + [self _log:@"RCVD" json:message]; + + NSString* responseId = message[@"responseId"]; + if (responseId) { + WVJBResponseCallback responseCallback = _responseCallbacks[responseId]; + responseCallback(message[@"responseData"]); + [_responseCallbacks removeObjectForKey:responseId]; + } else { + WVJBResponseCallback responseCallback = NULL; + NSString* callbackId = message[@"callbackId"]; + if (callbackId) { + responseCallback = ^(id responseData) { + if (responseData == nil) { + responseData = [NSNull null]; + } + + WVJBMessage* msg = @{ @"responseId":callbackId, @"responseData":responseData }; + [self _queueMessage:msg]; + }; + } else { + responseCallback = ^(id ignoreResponseData) { + // Do nothing + }; + } + + WVJBHandler handler; + if (message[@"handlerName"]) { + handler = _messageHandlers[message[@"handlerName"]]; + } else { + handler = _messageHandler; + } + + if (!handler) { + [NSException raise:@"WVJBNoHandlerException" format:@"No handler for message from JS: %@", message]; + } + + handler(message[@"data"], responseCallback); + } + } +} + +- (NSString *)_serializeMessage:(id)message { + return [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:message options:0 error:nil] encoding:NSUTF8StringEncoding]; +} + +- (NSArray*)_deserializeMessageJSON:(NSString *)messageJSON { + return [NSJSONSerialization JSONObjectWithData:[messageJSON dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil]; +} + +- (void)_log:(NSString *)action json:(id)json { + if (!logging) { return; } + if (![json isKindOfClass:[NSString class]]) { + json = [self _serializeMessage:json]; + } + if ([json length] > 500) { + NSLog(@"WVJB %@: %@ [...]", action, [json substringToIndex:500]); + } else { + NSLog(@"WVJB %@: %@", action, json); + } +} + + + + +/* WKWebView Specific Internals + ******************************/ + +- (void) _platformSpecificSetup:(WKWebView*)webView webViewDelegate:(id)webViewDelegate handler:(WVJBHandler)messageHandler resourceBundle:(NSBundle*)bundle{ + _messageHandler = messageHandler; + _webView = webView; + _webViewDelegate = webViewDelegate; + _messageHandlers = [NSMutableDictionary dictionary]; + _webView.navigationDelegate = self; + _resourceBundle = bundle; +} + +- (void) _platformSpecificDealloc { + _webView.navigationDelegate = nil; +} + + +- (void)WKFlushMessageQueue { + [_webView evaluateJavaScript:@"WebViewJavascriptBridge._fetchQueue();" completionHandler:^(NSString* result, NSError* error) { + [self _flushMessageQueue:result]; + }]; +} + +- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation +{ + if (webView != _webView) { return; } + + _numRequestsLoading--; + + if (_numRequestsLoading == 0) { + + [webView evaluateJavaScript:@"typeof WebViewJavascriptBridge == \'object\';" completionHandler:^(NSString *result, NSError *error) { + if(![result boolValue]){ + NSBundle *bundle = _resourceBundle ? _resourceBundle : [NSBundle mainBundle]; + NSString *filePath = [bundle pathForResource:@"WebViewJavascriptBridge.js" ofType:@"txt"]; + NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; + [webView evaluateJavaScript:js completionHandler:nil]; + } + }]; + } + + if (_startupMessageQueue) { + for (id queuedMessage in _startupMessageQueue) { + [self _dispatchMessage:queuedMessage]; + } + _startupMessageQueue = nil; + } + + __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFinishNavigation:)]) { + [strongDelegate webView:webView didFinishNavigation:navigation]; + } +} + + +- (void)webView:(WKWebView *)webView +decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction +decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { + if (webView != _webView) { return; } + NSURL *url = navigationAction.request.URL; + __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + if ([[url scheme] isEqualToString:kCustomProtocolScheme]) { + if ([[url host] isEqualToString:kQueueHasMessage]) { + [self WKFlushMessageQueue]; + } else { + NSLog(@"WKWebViewJavascriptBridge: WARNING: Received unknown WKWebViewJavascriptBridge command %@://%@", kCustomProtocolScheme, [url path]); + } + [webView stopLoading]; + } + + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) { + [_webViewDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler]; + } +} + +- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { + if (webView != _webView) { return; } + + _numRequestsLoading++; + + __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didStartProvisionalNavigation:)]) { + [strongDelegate webView:webView didStartProvisionalNavigation:navigation]; + } +} + + +- (void)webView:(WKWebView *)webView +didFailNavigation:(WKNavigation *)navigation + withError:(NSError *)error { + + if (webView != _webView) { return; } + + _numRequestsLoading--; + + __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailNavigation:withError:)]) { + [strongDelegate webView:webView didFailNavigation:navigation withError:error]; + } +} + + + +@end From b535dc2662d06a64bfd2b93739773d155248b7f3 Mon Sep 17 00:00:00 2001 From: lokimeyburg Date: Tue, 14 Oct 2014 17:17:58 -0700 Subject: [PATCH 100/285] Updated the example app to use WKWebView --- .../ExampleApp-iOS.xcodeproj/project.pbxproj | 4 ++ .../ExampleApp-iOS/ExampleAppViewController.h | 17 +++++++- .../ExampleApp-iOS/ExampleAppViewController.m | 40 ++++++++++++++----- Example Apps/ExampleApp.html | 1 + .../WKWebViewJavascriptBridge.h | 9 +---- .../WKWebViewJavascriptBridge.m | 2 + 6 files changed, 53 insertions(+), 20 deletions(-) diff --git a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj index 43943042..eaa1ace7 100644 --- a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 0E8082DB19EDC32300479452 /* WKWebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E8082DA19EDC32300479452 /* WKWebViewJavascriptBridge.m */; }; + 0E8082DD19EDD98700479452 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E8082DC19EDD98700479452 /* WebKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 2C1562B5176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt in Resources */ = {isa = PBXBuildFile; fileRef = 2C1562B4176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt */; }; 2C1562C0176BA63500B4AE50 /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */; }; 2C45CA2C1884AD520002A4E2 /* ExampleAppViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C45CA2B1884AD520002A4E2 /* ExampleAppViewController.m */; }; @@ -24,6 +25,7 @@ /* Begin PBXFileReference section */ 0E8082D919EDC32300479452 /* WKWebViewJavascriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKWebViewJavascriptBridge.h; sourceTree = ""; }; 0E8082DA19EDC32300479452 /* WKWebViewJavascriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WKWebViewJavascriptBridge.m; sourceTree = ""; }; + 0E8082DC19EDD98700479452 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; 2C1562A8176B9F6200B4AE50 /* WebViewJavascriptBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge.h; sourceTree = ""; }; 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge.m; sourceTree = ""; }; 2C1562B4176B9F8400B4AE50 /* WebViewJavascriptBridge.js.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebViewJavascriptBridge.js.txt; sourceTree = ""; }; @@ -48,6 +50,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0E8082DD19EDD98700479452 /* WebKit.framework in Frameworks */, 2CEB3EC01602563600548120 /* UIKit.framework in Frameworks */, 2CEB3EC21602563600548120 /* Foundation.framework in Frameworks */, 2CEB3EC41602563600548120 /* CoreGraphics.framework in Frameworks */, @@ -116,6 +119,7 @@ 2CEB3EBE1602563600548120 /* Frameworks */ = { isa = PBXGroup; children = ( + 0E8082DC19EDD98700479452 /* WebKit.framework */, 2CEB3EBF1602563600548120 /* UIKit.framework */, 2CEB3EC11602563600548120 /* Foundation.framework */, 2CEB3EC31602563600548120 /* CoreGraphics.framework */, diff --git a/Example Apps/ExampleApp-iOS/ExampleAppViewController.h b/Example Apps/ExampleApp-iOS/ExampleAppViewController.h index d2e25c2d..96028d55 100644 --- a/Example Apps/ExampleApp-iOS/ExampleAppViewController.h +++ b/Example Apps/ExampleApp-iOS/ExampleAppViewController.h @@ -8,6 +8,21 @@ #import -@interface ExampleAppViewController : UINavigationController + +#if defined(__IPHONE_8_0) + #import + #define EXAMPLE_WEBVIEW_TYPE WKWebView + #define EXAMPLE_WEBVIEW_DELEGATE_TYPE NSObject + #define EXAMPLE_WEBVIEW_DELEGATE_CONTROLLER UINavigationController + #define EXAMPLE_BRIDGE_TYPE WKWebViewJavascriptBridge +#else + #define EXAMPLE_WEBVIEW_TYPE UIWebView + #define EXAMPLE_WEBVIEW_DELEGATE_TYPE NSObject + #define EXAMPLE_WEBVIEW_DELEGATE_CONTROLLER UINavigationController + #define EXAMPLE_BRIDGE_TYPE WebViewJavascriptBridge +#endif + + +@interface ExampleAppViewController : EXAMPLE_WEBVIEW_DELEGATE_CONTROLLER @end diff --git a/Example Apps/ExampleApp-iOS/ExampleAppViewController.m b/Example Apps/ExampleApp-iOS/ExampleAppViewController.m index 3f1f7794..4865326a 100644 --- a/Example Apps/ExampleApp-iOS/ExampleAppViewController.m +++ b/Example Apps/ExampleApp-iOS/ExampleAppViewController.m @@ -7,10 +7,17 @@ // #import "ExampleAppViewController.h" + +#if defined(__IPHONE_8_0) +#import "WKWebViewJavascriptBridge.h" +# else #import "WebViewJavascriptBridge.h" +#endif @interface ExampleAppViewController () -@property WebViewJavascriptBridge* bridge; + +@property EXAMPLE_BRIDGE_TYPE* bridge; + @end @implementation ExampleAppViewController @@ -18,15 +25,26 @@ @implementation ExampleAppViewController - (void)viewWillAppear:(BOOL)animated { if (_bridge) { return; } - UIWebView* webView = [[UIWebView alloc] initWithFrame:self.view.bounds]; - [self.view addSubview:webView]; + #if defined(__IPHONE_8_0) + WKWebView* webView = [[WKWebView alloc] initWithFrame:self.view.bounds]; + webView.navigationDelegate = self; + [self.view addSubview:webView]; + [WKWebViewJavascriptBridge enableLogging]; + _bridge = [WKWebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"ObjC received message from JS: %@", data); + responseCallback(@"Response for message from ObjC"); + }]; + #else + UIWebView* webView = [[UIWebView alloc] initWithFrame:self.view.bounds]; + [self.view addSubview:webView]; + [WebViewJavascriptBridge enableLogging]; + _bridge = [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"ObjC received message from JS: %@", data); + responseCallback(@"Response for message from ObjC"); + }]; + #endif - [WebViewJavascriptBridge enableLogging]; - - _bridge = [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) { - NSLog(@"ObjC received message from JS: %@", data); - responseCallback(@"Response for message from ObjC"); - }]; + [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"testObjcCallback called: %@", data); @@ -53,7 +71,7 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView { NSLog(@"webViewDidFinishLoad"); } -- (void)renderButtons:(UIWebView*)webView { +- (void)renderButtons:(EXAMPLE_WEBVIEW_TYPE*)webView { UIFont* font = [UIFont fontWithName:@"HelveticaNeue" size:12.0]; UIButton *messageButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; @@ -92,7 +110,7 @@ - (void)callHandler:(id)sender { }]; } -- (void)loadExamplePage:(UIWebView*)webView { +- (void)loadExamplePage:(EXAMPLE_WEBVIEW_TYPE*)webView { NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; NSURL *baseURL = [NSURL fileURLWithPath:htmlPath]; diff --git a/Example Apps/ExampleApp.html b/Example Apps/ExampleApp.html index d31f1fb1..4278a8ad 100644 --- a/Example Apps/ExampleApp.html +++ b/Example Apps/ExampleApp.html @@ -1,5 +1,6 @@ +