diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..81a6b69c --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,21 @@ +# WVJB Bug Report + +Thanks for reporting an issue with WebViewJavascriptBridge. + +### Do these 4 things and I will fix your problem! + +1. Go to https://github.com/marcuswestin/WebViewJavascriptBridge and click Fork. +2. Clone your fork, `cd` into it and run `make test`. All tests should pass! +3. Edit `Tests/WebViewJavascriptBridgeTests/BridgeTests.m` and create a new, failing test which demostrates your issue. +4. Create a pull request for https://github.com/marcuswestin/WebViewJavascriptBridge + +#### That's it! + +I will take it from there and promise that I'll fix your problem ASAP. + +#### If you don't do this then I can't help you! + +And I probably won't :) + +Cheers, +@marcuswestin diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..920af1c5 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,13 @@ +## Before your create your PR: + +#### Please add tests for any new or changed functionality! + +1. Edit `Tests/WebViewJavascriptBridgeTests/BridgeTests.m` +2. Create a new test which demostrates your changes. +3. Run `make test` and make sure your test is passing +4. That's it! + +#### Thanks for improving WebViewJavascriptBridge! + +Cheers, +@marcuswestin diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0503bac4..00000000 --- a/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: objective-c -script: - - make test \ No newline at end of file diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 00000000..ddda54c3 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1 @@ +Copyright (c) 2023 - Marcus Westin \ No newline at end of file diff --git a/Changelog b/Changelog index 362f9fdd..af90a6d3 100644 --- a/Changelog +++ b/Changelog @@ -13,8 +13,14 @@ Release Checklist Version History --------------- -Next version -+ Pretty-print json in log messages +v5.1.1 ++ Swift unit tests and examples ++ Implement removeHandler + +v5.1.0 ++ A single instantiation function for all webview types. ++ Improved test runner. ++ New instructions & templates for github issues and pull requests. v5.0.5 + Run all tests for both UIWebView and WKWebView webviews/bridges. diff --git a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj index 410ce82c..d08ca0ab 100644 --- a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj @@ -164,7 +164,7 @@ 2C136A1917641106004C7401 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0510; + LastUpgradeCheck = 0810; ORGANIZATIONNAME = "Marcus Westin"; }; buildConfigurationList = 2C136A1C17641106004C7401 /* Build configuration list for PBXProject "ExampleApp-OSX" */; @@ -241,15 +241,22 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -258,7 +265,9 @@ GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.8; ONLY_ACTIVE_ARCH = YES; @@ -273,18 +282,26 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.8; SDKROOT = macosx; @@ -299,6 +316,7 @@ GCC_PREFIX_HEADER = "ExampleApp-OSX/ExampleApp-OSX-Prefix.pch"; INFOPLIST_FILE = "ExampleApp-OSX/ExampleApp-OSX-Info.plist"; MACOSX_DEPLOYMENT_TARGET = 10.7; + PRODUCT_BUNDLE_IDENTIFIER = "WebViewJavascriptBridge.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -312,6 +330,7 @@ GCC_PREFIX_HEADER = "ExampleApp-OSX/ExampleApp-OSX-Prefix.pch"; INFOPLIST_FILE = "ExampleApp-OSX/ExampleApp-OSX-Info.plist"; MACOSX_DEPLOYMENT_TARGET = 10.7; + PRODUCT_BUNDLE_IDENTIFIER = "WebViewJavascriptBridge.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/Example Apps/ExampleApp-OSX/AppDelegate.m b/Example Apps/ExampleApp-OSX/AppDelegate.m index 970c64d1..5677342a 100644 --- a/Example Apps/ExampleApp-OSX/AppDelegate.m +++ b/Example Apps/ExampleApp-OSX/AppDelegate.m @@ -9,13 +9,12 @@ #import "AppDelegate.h" #import #import "WebViewJavascriptBridge.h" -#import "WKWebViewJavascriptBridge.h" @implementation AppDelegate { WebView* _webView; WKWebView *_WKWebView; WebViewJavascriptBridge* _bridge; - WKWebViewJavascriptBridge* _WKBridge; + WebViewJavascriptBridge* _WKBridge; NSView* _WKWebViewWrapper; } @@ -56,13 +55,14 @@ - (void)_configureWebview { // Load Page NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; NSString* html = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; - [[_webView mainFrame] loadHTMLString:html baseURL:nil]; + NSURL *baseURL = [NSURL fileURLWithPath:htmlPath]; + [[_webView mainFrame] loadHTMLString:html baseURL: baseURL]; } - (void)_configureWKWebview { // Create Bridge - _WKBridge = [WKWebViewJavascriptBridge bridgeForWebView:_WKWebView]; + _WKBridge = [WebViewJavascriptBridge bridgeForWebView:_WKWebView]; [_WKBridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"testObjcCallback called: %@", data); @@ -89,7 +89,8 @@ - (void)_configureWKWebview { // Load Page NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; NSString* html = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; - [_WKWebView loadHTMLString:html baseURL:nil]; + NSURL *baseURL = [NSURL fileURLWithPath:htmlPath]; + [_WKWebView loadHTMLString:html baseURL:baseURL]; } -(void)_toggleExample { diff --git a/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist index 846d4e33..b9f1feaa 100644 --- a/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist +++ b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist @@ -9,7 +9,7 @@ CFBundleIconFile CFBundleIdentifier - WebViewJavascriptBridge.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj index c1039a80..324a5b06 100644 --- a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj +++ b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj @@ -20,8 +20,6 @@ 2CA0465C1711AC8E006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */; }; 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 */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -59,8 +57,6 @@ files = ( 0E4E9D4C1A101E0B00043087 /* WebKit.framework in Frameworks */, 2CEB3EC01602563600548120 /* UIKit.framework in Frameworks */, - 2CEB3EC21602563600548120 /* Foundation.framework in Frameworks */, - 2CEB3EC41602563600548120 /* CoreGraphics.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -117,6 +113,7 @@ 2CA045B617117439006DEE8B /* ExampleApp-iOS */, 2CEB3EBE1602563600548120 /* Frameworks */, 2CEB3EBC1602563600548120 /* Products */, + 81A733051B2F9C5795D856E4 /* Pods */, ); sourceTree = ""; }; @@ -139,6 +136,13 @@ name = Frameworks; sourceTree = ""; }; + 81A733051B2F9C5795D856E4 /* Pods */ = { + isa = PBXGroup; + children = ( + ); + name = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -165,8 +169,13 @@ 2CEB3EB21602563600548120 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0500; + LastUpgradeCheck = 0810; ORGANIZATIONNAME = "Marcus Westin"; + TargetAttributes = { + 2CEB3EBA1602563600548120 = { + LastSwiftMigration = 0820; + }; + }; }; buildConfigurationList = 2CEB3EB51602563600548120 /* Build configuration list for PBXProject "ExampleApp-iOS" */; compatibilityVersion = "Xcode 3.2"; @@ -235,21 +244,35 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = 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_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -262,14 +285,27 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -279,11 +315,16 @@ 2CEB3ED41602563600548120 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ExampleApp-iOS/ExampleApp-iOS-Prefix.pch"; INFOPLIST_FILE = "ExampleApp-iOS/ExampleApp-iOS-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.example.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "ExampleApp-iOS"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; WRAPPER_EXTENSION = app; }; name = Debug; @@ -291,11 +332,15 @@ 2CEB3ED51602563600548120 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ExampleApp-iOS/ExampleApp-iOS-Prefix.pch"; INFOPLIST_FILE = "ExampleApp-iOS/ExampleApp-iOS-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.example.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "ExampleApp-iOS"; + SWIFT_VERSION = 3.0; WRAPPER_EXTENSION = app; }; name = Release; diff --git a/Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist b/Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist index 81d25998..3eb70251 100644 --- a/Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist +++ b/Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.example.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Example Apps/ExampleApp-iOS/ExampleUIWebViewController.m b/Example Apps/ExampleApp-iOS/ExampleUIWebViewController.m index d94f501a..f988a014 100644 --- a/Example Apps/ExampleApp-iOS/ExampleUIWebViewController.m +++ b/Example Apps/ExampleApp-iOS/ExampleUIWebViewController.m @@ -24,6 +24,7 @@ - (void)viewWillAppear:(BOOL)animated { [WebViewJavascriptBridge enableLogging]; _bridge = [WebViewJavascriptBridge bridgeForWebView:webView]; + [_bridge setWebViewDelegate:self]; [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"testObjcCallback called: %@", data); @@ -45,21 +46,32 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView { } - (void)renderButtons:(UIWebView*)webView { - UIFont* font = [UIFont fontWithName:@"HelveticaNeue" size:12.0]; + UIFont* font = [UIFont fontWithName:@"HelveticaNeue" size:11.0]; 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(10, 400, 100, 35); + callbackButton.frame = CGRectMake(0, 400, 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(110, 400, 100, 35); + reloadButton.frame = CGRectMake(90, 400, 100, 35); reloadButton.titleLabel.font = font; + + UIButton* safetyTimeoutButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; + [safetyTimeoutButton setTitle:@"Disable safety timeout" forState:UIControlStateNormal]; + [safetyTimeoutButton addTarget:self action:@selector(disableSafetyTimeout) forControlEvents:UIControlEventTouchUpInside]; + [self.view insertSubview:safetyTimeoutButton aboveSubview:webView]; + safetyTimeoutButton.frame = CGRectMake(190, 400, 120, 35); + safetyTimeoutButton.titleLabel.font = font; +} + +- (void)disableSafetyTimeout { + [self.bridge disableJavscriptAlertBoxSafetyTimeout]; } - (void)callHandler:(id)sender { diff --git a/Example Apps/ExampleApp-iOS/ExampleWKWebViewController.m b/Example Apps/ExampleApp-iOS/ExampleWKWebViewController.m index 60df23e8..f9d4ac79 100644 --- a/Example Apps/ExampleApp-iOS/ExampleWKWebViewController.m +++ b/Example Apps/ExampleApp-iOS/ExampleWKWebViewController.m @@ -7,11 +7,11 @@ // #import "ExampleWKWebViewController.h" -#import "WKWebViewJavascriptBridge.h" +#import "WebViewJavascriptBridge.h" @interface ExampleWKWebViewController () -@property WKWebViewJavascriptBridge* bridge; +@property WebViewJavascriptBridge* bridge; @end @@ -23,8 +23,9 @@ - (void)viewWillAppear:(BOOL)animated { WKWebView* webView = [[NSClassFromString(@"WKWebView") alloc] initWithFrame:self.view.bounds]; webView.navigationDelegate = self; [self.view addSubview:webView]; - [WKWebViewJavascriptBridge enableLogging]; - _bridge = [WKWebViewJavascriptBridge bridgeForWebView:webView]; + [WebViewJavascriptBridge enableLogging]; + _bridge = [WebViewJavascriptBridge bridgeForWebView:webView]; + [_bridge setWebViewDelegate:self]; [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"testObjcCallback called: %@", data); @@ -37,11 +38,11 @@ - (void)viewWillAppear:(BOOL)animated { [self loadExamplePage:webView]; } -- (void)webViewDidStartLoad:(UIWebView *)webView { +- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { NSLog(@"webViewDidStartLoad"); } -- (void)webViewDidFinishLoad:(UIWebView *)webView { +- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { NSLog(@"webViewDidFinishLoad"); } diff --git a/Example Apps/ExampleApp.html b/Example Apps/ExampleApp.html index 646806a5..06e7dc8a 100644 --- a/Example Apps/ExampleApp.html +++ b/Example Apps/ExampleApp.html @@ -20,7 +20,7 @@

WebViewJavascriptBridge Demo

window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement('iframe'); WVJBIframe.style.display = 'none'; - WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; + WVJBIframe.src = 'https://__bridge_loaded__'; document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) } diff --git a/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS.xcodeproj/project.pbxproj b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS.xcodeproj/project.pbxproj new file mode 100644 index 00000000..51bd94d7 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS.xcodeproj/project.pbxproj @@ -0,0 +1,568 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 2C85D0041E12D13E00B5BB1F /* echo.html in Resources */ = {isa = PBXBuildFile; fileRef = 2C85D0031E12D13E00B5BB1F /* echo.html */; }; + 2C85D0051E12D13E00B5BB1F /* echo.html in Resources */ = {isa = PBXBuildFile; fileRef = 2C85D0031E12D13E00B5BB1F /* echo.html */; }; + 2CF20A991E12BB3F00D3009D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CF20A981E12BB3F00D3009D /* AppDelegate.swift */; }; + 2CF20A9B1E12BB3F00D3009D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CF20A9A1E12BB3F00D3009D /* ViewController.swift */; }; + 2CF20A9E1E12BB3F00D3009D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2CF20A9C1E12BB3F00D3009D /* Main.storyboard */; }; + 2CF20AA01E12BB3F00D3009D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2CF20A9F1E12BB3F00D3009D /* Assets.xcassets */; }; + 2CF20AA31E12BB3F00D3009D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2CF20AA11E12BB3F00D3009D /* LaunchScreen.storyboard */; }; + 2CF20AAE1E12BB3F00D3009D /* ExampleSwiftApp_iOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CF20AAD1E12BB3F00D3009D /* ExampleSwiftApp_iOSTests.swift */; }; + D8CEA1425EC257C350E1AB7B /* Pods_ExampleSwiftApp_iOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F83CA56A2551209150BE3026 /* Pods_ExampleSwiftApp_iOSTests.framework */; }; + F2E5C0A8E08BEBA27AF5E74A /* Pods_ExampleSwiftApp_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEA6EDCA550904DB02B48E33 /* Pods_ExampleSwiftApp_iOS.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 2CF20AAA1E12BB3F00D3009D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 2CF20A8D1E12BB3F00D3009D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2CF20A941E12BB3F00D3009D; + remoteInfo = "ExampleSwiftApp-iOS"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 2C85D0031E12D13E00B5BB1F /* echo.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = echo.html; sourceTree = ""; }; + 2CF20A951E12BB3F00D3009D /* ExampleSwiftApp-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ExampleSwiftApp-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2CF20A981E12BB3F00D3009D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 2CF20A9A1E12BB3F00D3009D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 2CF20A9D1E12BB3F00D3009D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 2CF20A9F1E12BB3F00D3009D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 2CF20AA21E12BB3F00D3009D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 2CF20AA41E12BB3F00D3009D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2CF20AA91E12BB3F00D3009D /* ExampleSwiftApp-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ExampleSwiftApp-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2CF20AAD1E12BB3F00D3009D /* ExampleSwiftApp_iOSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleSwiftApp_iOSTests.swift; sourceTree = ""; }; + 2CF20AAF1E12BB3F00D3009D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 428486AD61C115757F5B2D0E /* Pods-ExampleSwiftApp-iOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleSwiftApp-iOSTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.release.xcconfig"; sourceTree = ""; }; + 501BFA93F6923681FFC52CCF /* Pods-ExampleSwiftApp-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleSwiftApp-iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.debug.xcconfig"; sourceTree = ""; }; + 540FA2D8150D626B9E77FAB0 /* Pods-ExampleSwiftApp-iOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleSwiftApp-iOSTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.debug.xcconfig"; sourceTree = ""; }; + BEA6EDCA550904DB02B48E33 /* Pods_ExampleSwiftApp_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ExampleSwiftApp_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C5654CD94CAAAA26115AFE32 /* Pods-ExampleSwiftApp-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleSwiftApp-iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.release.xcconfig"; sourceTree = ""; }; + F83CA56A2551209150BE3026 /* Pods_ExampleSwiftApp_iOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ExampleSwiftApp_iOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 2CF20A921E12BB3F00D3009D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F2E5C0A8E08BEBA27AF5E74A /* Pods_ExampleSwiftApp_iOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2CF20AA61E12BB3F00D3009D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D8CEA1425EC257C350E1AB7B /* Pods_ExampleSwiftApp_iOSTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2CF20A8C1E12BB3F00D3009D = { + isa = PBXGroup; + children = ( + 2C85D0031E12D13E00B5BB1F /* echo.html */, + 2CF20A971E12BB3F00D3009D /* ExampleSwiftApp-iOS */, + 2CF20AAC1E12BB3F00D3009D /* ExampleSwiftApp-iOSTests */, + 2CF20A961E12BB3F00D3009D /* Products */, + 9F0299D3BBA025224C110345 /* Pods */, + 6303D0CF3CEDE121D7B2EAE7 /* Frameworks */, + ); + sourceTree = ""; + }; + 2CF20A961E12BB3F00D3009D /* Products */ = { + isa = PBXGroup; + children = ( + 2CF20A951E12BB3F00D3009D /* ExampleSwiftApp-iOS.app */, + 2CF20AA91E12BB3F00D3009D /* ExampleSwiftApp-iOSTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 2CF20A971E12BB3F00D3009D /* ExampleSwiftApp-iOS */ = { + isa = PBXGroup; + children = ( + 2CF20A981E12BB3F00D3009D /* AppDelegate.swift */, + 2CF20A9A1E12BB3F00D3009D /* ViewController.swift */, + 2CF20A9C1E12BB3F00D3009D /* Main.storyboard */, + 2CF20A9F1E12BB3F00D3009D /* Assets.xcassets */, + 2CF20AA11E12BB3F00D3009D /* LaunchScreen.storyboard */, + 2CF20AA41E12BB3F00D3009D /* Info.plist */, + ); + path = "ExampleSwiftApp-iOS"; + sourceTree = ""; + }; + 2CF20AAC1E12BB3F00D3009D /* ExampleSwiftApp-iOSTests */ = { + isa = PBXGroup; + children = ( + 2CF20AAD1E12BB3F00D3009D /* ExampleSwiftApp_iOSTests.swift */, + 2CF20AAF1E12BB3F00D3009D /* Info.plist */, + ); + path = "ExampleSwiftApp-iOSTests"; + sourceTree = ""; + }; + 6303D0CF3CEDE121D7B2EAE7 /* Frameworks */ = { + isa = PBXGroup; + children = ( + BEA6EDCA550904DB02B48E33 /* Pods_ExampleSwiftApp_iOS.framework */, + F83CA56A2551209150BE3026 /* Pods_ExampleSwiftApp_iOSTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9F0299D3BBA025224C110345 /* Pods */ = { + isa = PBXGroup; + children = ( + 501BFA93F6923681FFC52CCF /* Pods-ExampleSwiftApp-iOS.debug.xcconfig */, + C5654CD94CAAAA26115AFE32 /* Pods-ExampleSwiftApp-iOS.release.xcconfig */, + 540FA2D8150D626B9E77FAB0 /* Pods-ExampleSwiftApp-iOSTests.debug.xcconfig */, + 428486AD61C115757F5B2D0E /* Pods-ExampleSwiftApp-iOSTests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 2CF20A941E12BB3F00D3009D /* ExampleSwiftApp-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2CF20AB21E12BB3F00D3009D /* Build configuration list for PBXNativeTarget "ExampleSwiftApp-iOS" */; + buildPhases = ( + E1EE87376320127A646E0030 /* [CP] Check Pods Manifest.lock */, + 2CF20A911E12BB3F00D3009D /* Sources */, + 2CF20A921E12BB3F00D3009D /* Frameworks */, + 2CF20A931E12BB3F00D3009D /* Resources */, + BA4C674FF1CCCC87D20090E4 /* [CP] Embed Pods Frameworks */, + F106D79C2CD5F06E8F3F438D /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "ExampleSwiftApp-iOS"; + productName = "ExampleSwiftApp-iOS"; + productReference = 2CF20A951E12BB3F00D3009D /* ExampleSwiftApp-iOS.app */; + productType = "com.apple.product-type.application"; + }; + 2CF20AA81E12BB3F00D3009D /* ExampleSwiftApp-iOSTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2CF20AB51E12BB3F00D3009D /* Build configuration list for PBXNativeTarget "ExampleSwiftApp-iOSTests" */; + buildPhases = ( + 4889AB1A10A2C9552E6BBD23 /* [CP] Check Pods Manifest.lock */, + 2CF20AA51E12BB3F00D3009D /* Sources */, + 2CF20AA61E12BB3F00D3009D /* Frameworks */, + 2CF20AA71E12BB3F00D3009D /* Resources */, + 329B179F6DF51F14F9B1629B /* [CP] Embed Pods Frameworks */, + 50CDAEBCB453B9875E9F7147 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 2CF20AAB1E12BB3F00D3009D /* PBXTargetDependency */, + ); + name = "ExampleSwiftApp-iOSTests"; + productName = "ExampleSwiftApp-iOSTests"; + productReference = 2CF20AA91E12BB3F00D3009D /* ExampleSwiftApp-iOSTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 2CF20A8D1E12BB3F00D3009D /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0820; + LastUpgradeCheck = 0820; + ORGANIZATIONNAME = "Marcus Westin"; + TargetAttributes = { + 2CF20A941E12BB3F00D3009D = { + CreatedOnToolsVersion = 8.2.1; + LastSwiftMigration = 0910; + ProvisioningStyle = Automatic; + }; + 2CF20AA81E12BB3F00D3009D = { + CreatedOnToolsVersion = 8.2.1; + LastSwiftMigration = 0910; + ProvisioningStyle = Automatic; + TestTargetID = 2CF20A941E12BB3F00D3009D; + }; + }; + }; + buildConfigurationList = 2CF20A901E12BB3F00D3009D /* Build configuration list for PBXProject "ExampleSwiftApp-iOS" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 2CF20A8C1E12BB3F00D3009D; + productRefGroup = 2CF20A961E12BB3F00D3009D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2CF20A941E12BB3F00D3009D /* ExampleSwiftApp-iOS */, + 2CF20AA81E12BB3F00D3009D /* ExampleSwiftApp-iOSTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 2CF20A931E12BB3F00D3009D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2CF20AA31E12BB3F00D3009D /* LaunchScreen.storyboard in Resources */, + 2CF20AA01E12BB3F00D3009D /* Assets.xcassets in Resources */, + 2CF20A9E1E12BB3F00D3009D /* Main.storyboard in Resources */, + 2C85D0041E12D13E00B5BB1F /* echo.html in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2CF20AA71E12BB3F00D3009D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2C85D0051E12D13E00B5BB1F /* echo.html in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 329B179F6DF51F14F9B1629B /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 4889AB1A10A2C9552E6BBD23 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 50CDAEBCB453B9875E9F7147 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + BA4C674FF1CCCC87D20090E4 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + E1EE87376320127A646E0030 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + F106D79C2CD5F06E8F3F438D /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2CF20A911E12BB3F00D3009D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2CF20A9B1E12BB3F00D3009D /* ViewController.swift in Sources */, + 2CF20A991E12BB3F00D3009D /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2CF20AA51E12BB3F00D3009D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2CF20AAE1E12BB3F00D3009D /* ExampleSwiftApp_iOSTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 2CF20AAB1E12BB3F00D3009D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 2CF20A941E12BB3F00D3009D /* ExampleSwiftApp-iOS */; + targetProxy = 2CF20AAA1E12BB3F00D3009D /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 2CF20A9C1E12BB3F00D3009D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 2CF20A9D1E12BB3F00D3009D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 2CF20AA11E12BB3F00D3009D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 2CF20AA21E12BB3F00D3009D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 2CF20AB01E12BB3F00D3009D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 2CF20AB11E12BB3F00D3009D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 2CF20AB31E12BB3F00D3009D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 501BFA93F6923681FFC52CCF /* Pods-ExampleSwiftApp-iOS.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "ExampleSwiftApp-iOS/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "in.marcuswest.ExampleSwiftApp-iOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; + }; + name = Debug; + }; + 2CF20AB41E12BB3F00D3009D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C5654CD94CAAAA26115AFE32 /* Pods-ExampleSwiftApp-iOS.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "ExampleSwiftApp-iOS/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "in.marcuswest.ExampleSwiftApp-iOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; + }; + name = Release; + }; + 2CF20AB61E12BB3F00D3009D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 540FA2D8150D626B9E77FAB0 /* Pods-ExampleSwiftApp-iOSTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + INFOPLIST_FILE = "ExampleSwiftApp-iOSTests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "in.marcuswest.ExampleSwiftApp-iOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ExampleSwiftApp-iOS.app/ExampleSwiftApp-iOS"; + }; + name = Debug; + }; + 2CF20AB71E12BB3F00D3009D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 428486AD61C115757F5B2D0E /* Pods-ExampleSwiftApp-iOSTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + INFOPLIST_FILE = "ExampleSwiftApp-iOSTests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "in.marcuswest.ExampleSwiftApp-iOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ExampleSwiftApp-iOS.app/ExampleSwiftApp-iOS"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2CF20A901E12BB3F00D3009D /* Build configuration list for PBXProject "ExampleSwiftApp-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2CF20AB01E12BB3F00D3009D /* Debug */, + 2CF20AB11E12BB3F00D3009D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2CF20AB21E12BB3F00D3009D /* Build configuration list for PBXNativeTarget "ExampleSwiftApp-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2CF20AB31E12BB3F00D3009D /* Debug */, + 2CF20AB41E12BB3F00D3009D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2CF20AB51E12BB3F00D3009D /* Build configuration list for PBXNativeTarget "ExampleSwiftApp-iOSTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2CF20AB61E12BB3F00D3009D /* Debug */, + 2CF20AB71E12BB3F00D3009D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 2CF20A8D1E12BB3F00D3009D /* Project object */; +} diff --git a/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS.xcworkspace/contents.xcworkspacedata b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..c6b1391d --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/AppDelegate.swift b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/AppDelegate.swift new file mode 100644 index 00000000..808eae5c --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/AppDelegate.swift @@ -0,0 +1,47 @@ +// +// AppDelegate.swift +// ExampleSwiftApp-iOS +// +// Created by John Marcus Westin on 12/27/16. +// Copyright © 2016 Marcus Westin. All rights reserved. +// + +import UIKit +import WebViewJavascriptBridge + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..36d2c80d --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/Base.lproj/LaunchScreen.storyboard b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..fdf3f97d --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/Base.lproj/Main.storyboard b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/Base.lproj/Main.storyboard new file mode 100644 index 00000000..273375fc --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/Info.plist b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/Info.plist new file mode 100644 index 00000000..d0524738 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/ViewController.swift b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/ViewController.swift new file mode 100644 index 00000000..f6eb0351 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS/ViewController.swift @@ -0,0 +1,25 @@ +// +// ViewController.swift +// ExampleSwiftApp-iOS +// +// Created by John Marcus Westin on 12/27/16. +// Copyright © 2016 Marcus Westin. All rights reserved. +// + +import UIKit + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + +} + diff --git a/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOSTests/ExampleSwiftApp_iOSTests.swift b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOSTests/ExampleSwiftApp_iOSTests.swift new file mode 100644 index 00000000..c2a3b31a --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOSTests/ExampleSwiftApp_iOSTests.swift @@ -0,0 +1,211 @@ +// +// ExampleSwiftApp_iOSTests.swift +// ExampleSwiftApp-iOSTests +// +// Created by John Marcus Westin on 12/27/16. +// Copyright © 2016 Marcus Westin. All rights reserved. +// + +import XCTest +import WebKit + +import WebViewJavascriptBridge +@testable import ExampleSwiftApp_iOS + +let timeout: Double = 3 + +class ExampleSwiftApp_iOSTests: XCTestCase { + var uiWebView: UIWebView = UIWebView.init() + var wkWebView: WKWebView = WKWebView.init() + var bridgeRefs: NSMutableArray = [] + + override func setUp() { + super.setUp() + + let rootVC = (UIApplication.shared.delegate as! AppDelegate).window!.rootViewController! + var frame = rootVC.view.bounds + frame.size.height /= 2 + + uiWebView = UIWebView.init(frame: frame) + uiWebView.backgroundColor = UIColor.blue + rootVC.view.addSubview(uiWebView) + + frame.origin.y += frame.size.height + wkWebView = WKWebView.init(frame: frame) + wkWebView.backgroundColor = UIColor.red + rootVC.view.addSubview(wkWebView) + + bridgeRefs = NSMutableArray.init() + } + + override func tearDown() { + super.tearDown() + uiWebView.removeFromSuperview() + wkWebView.removeFromSuperview() + } + + func bridgeForWebView(_ webView: Any) -> WebViewJavascriptBridge { + let bridge = WebViewJavascriptBridge.init(webView)! + bridgeRefs.add(bridge) + return bridge + } + + func loadEchoSample(_ webView: Any) { + let request = URLRequest.init(url: Bundle.main.url(forResource: "echo", withExtension: "html")!) + if webView is UIWebView { + (webView as! UIWebView).loadRequest(request) + } else { + (webView as! WKWebView).load(request) + } + } + + func testSetup() { + _testSetup(webView: uiWebView) + _testSetup(webView: wkWebView) + waitForExpectations(timeout: timeout, handler: nil) + } + func _testSetup(webView: Any) { + let setup = self.expectation(description: "Setup completed") + let bridge = self.bridgeForWebView(webView) + bridge.registerHandler("Greet") { (data, responseCallback) in + XCTAssertEqual(data as! String, "Hello world") + setup.fulfill() + } + XCTAssertNotNil(bridge) + self.loadEchoSample(webView) + } + + + func testEchoHandler() { + _testEchoHandler(uiWebView) + _testEchoHandler(wkWebView) + waitForExpectations(timeout: timeout, handler: nil) + } + func _testEchoHandler(_ webView: Any) { + let bridge = bridgeForWebView(webView) + + let callbackInvoked = expectation(description: "Callback invoked") + bridge.callHandler("echoHandler", data:"testEchoHandler") { (responseData) in + XCTAssertEqual(responseData as! String, "testEchoHandler"); + callbackInvoked.fulfill() + }; + + loadEchoSample(webView); + } + + func testEchoHandlerAfterSetup() { + _testEchoHandlerAfterSetup(uiWebView) + _testEchoHandlerAfterSetup(wkWebView) + waitForExpectations(timeout: timeout, handler: nil) + } + func _testEchoHandlerAfterSetup(_ webView: Any) { + let bridge = bridgeForWebView(webView) + + let callbackInvoked = expectation(description: "Callback invoked") + loadEchoSample(webView); + DispatchQueue.main.asyncAfter(deadline: .now() + 0.150) { + bridge.callHandler("echoHandler", data:"testEchoHandler") { (responseData) in + XCTAssertEqual(responseData as! String, "testEchoHandler") + callbackInvoked.fulfill() + } + } + } + + func testObjectEncoding() { + _testObjectEncoding(uiWebView) + _testObjectEncoding(wkWebView) + waitForExpectations(timeout: timeout, handler: nil) + } + func _testObjectEncoding(_ webView: Any) { + let bridge = bridgeForWebView(webView) + + func echoObject(_ object: Any) { + let callbackInvoked = expectation(description: "Callback invoked") + bridge.callHandler("echoHandler", data:object) { (responseData) in + if (object is NSDictionary) { + XCTAssertEqual(responseData as! NSDictionary, object as! NSDictionary) + } else if (object is NSArray) { + XCTAssertEqual(responseData as! NSArray, object as! NSArray) + } + callbackInvoked.fulfill() + } + } + + echoObject("A string sent over the wire"); + echoObject("A string with '\"'/\\"); + echoObject([1, 2, 3]); + echoObject(["a":1, "b":2]); + + loadEchoSample(webView); + } + + func testJavascriptReceiveResponse() { + _testJavascriptReceiveResponse(uiWebView) + _testJavascriptReceiveResponse(wkWebView) + waitForExpectations(timeout: timeout, handler: nil) + } + func _testJavascriptReceiveResponse(_ webView: Any) { + let bridge = bridgeForWebView(webView) + loadEchoSample(webView); + let callbackInvoked = expectation(description: "Callback invoked") + bridge.registerHandler("objcEchoToJs") { (data, responseCallback) in + XCTAssertEqual(data as! NSDictionary, ["foo":"bar"]); + responseCallback!(data) + } + bridge.callHandler("jsRcvResponseTest", data:nil) { (responseData) in + XCTAssertEqual(responseData as! String, "Response from JS"); + callbackInvoked.fulfill() + } + } + + func testJavascriptReceiveResponseWithoutSafetyTimeout() { + _testJavascriptReceiveResponseWithoutSafetyTimeout(uiWebView) + _testJavascriptReceiveResponseWithoutSafetyTimeout(wkWebView) + waitForExpectations(timeout: timeout, handler: nil) + } + func _testJavascriptReceiveResponseWithoutSafetyTimeout(_ webView: Any) { + let bridge = bridgeForWebView(webView) + bridge.disableJavscriptAlertBoxSafetyTimeout() + loadEchoSample(webView); + let callbackInvoked = expectation(description: "Callback invoked") + bridge.registerHandler("objcEchoToJs") { (data, responseCallback) in + XCTAssertEqual(data as! NSDictionary, ["foo":"bar"]); + responseCallback!(data); + } + bridge.callHandler("jsRcvResponseTest", data:nil) { (responseData) in + XCTAssertEqual(responseData as! String, "Response from JS"); + callbackInvoked.fulfill() + } + } + + func testRemoveHandler() { + _testRemoveHandler(uiWebView) + _testRemoveHandler(wkWebView) + waitForExpectations(timeout: timeout, handler: nil) + } + func _testRemoveHandler(_ webView: Any) { + loadEchoSample(webView); + let bridge = bridgeForWebView(webView) + let callbackNotInvoked = expectation(description: "Callback invoked") + var count = 0 + bridge.registerHandler("objcEchoToJs") { (data, callback) in + count += 1 + callback!(data) + } + bridge.callHandler("jsRcvResponseTest", data:nil) { (responseData) in + XCTAssertEqual(responseData as! String, "Response from JS"); + bridge.removeHandler("objcEchoToJs") + bridge.callHandler("jsRcvResponseTest", data:nil) { (responseData) in + // Since we have removed the "objcEchoToJs" handler, and since the + // echo.html javascript won't call the response callback until it has + // received a response from "objcEchoToJs", we should never get here + XCTAssert(false) + } + bridge.callHandler("echoHandler", data:nil ) { (responseData) in + XCTAssertEqual(count, 1) + callbackNotInvoked.fulfill() + } + } + } + +} diff --git a/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOSTests/Info.plist b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOSTests/Info.plist new file mode 100644 index 00000000..6c6c23c4 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOSTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Example Apps/ExampleSwiftApp-iOS/Podfile b/Example Apps/ExampleSwiftApp-iOS/Podfile new file mode 100644 index 00000000..504f6f15 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Podfile @@ -0,0 +1,18 @@ +project 'ExampleSwiftApp-iOS.xcodeproj' + +# Uncomment the next line to define a global platform for your project +platform :ios, '9.0' +use_frameworks! + +target 'ExampleSwiftApp-iOS' do + # Comment the next line if you're not using Swift and don't want to use dynamic frameworks + + pod 'WebViewJavascriptBridge', :path => '../..' + + target 'ExampleSwiftApp-iOSTests' do + inherit! :search_paths + + pod 'WebViewJavascriptBridge', :path => '../..' + end + +end diff --git a/Example Apps/ExampleSwiftApp-iOS/Podfile.lock b/Example Apps/ExampleSwiftApp-iOS/Podfile.lock new file mode 100644 index 00000000..0f348683 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - WebViewJavascriptBridge (6.0.2) + +DEPENDENCIES: + - WebViewJavascriptBridge (from `../..`) + +EXTERNAL SOURCES: + WebViewJavascriptBridge: + :path: ../.. + +SPEC CHECKSUMS: + WebViewJavascriptBridge: 791ee0e26d1bf15efe5fb7fb9666a71a19b89d77 + +PODFILE CHECKSUM: f657cfcc5a24b7c7f0c7781719b73d4a834bc276 + +COCOAPODS: 1.1.1 diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Local Podspecs/WebViewJavascriptBridge.podspec.json b/Example Apps/ExampleSwiftApp-iOS/Pods/Local Podspecs/WebViewJavascriptBridge.podspec.json new file mode 100644 index 00000000..5fb7055c --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Local Podspecs/WebViewJavascriptBridge.podspec.json @@ -0,0 +1,35 @@ +{ + "name": "WebViewJavascriptBridge", + "version": "6.0.2", + "summary": "An iOS & OSX bridge for sending messages between Obj-C/Swift and JavaScript in WKWebViews, UIWebViews & WebViews.", + "homepage": "https://github.com/marcuswestin/WebViewJavascriptBridge", + "license": { + "type": "MIT", + "file": "LICENSE" + }, + "authors": { + "marcuswestin": "marcus.westin@gmail.com" + }, + "source": { + "git": "https://github.com/marcuswestin/WebViewJavascriptBridge.git", + "tag": "v6.0.2" + }, + "platforms": { + "ios": "5.0", + "osx": "" + }, + "requires_arc": true, + "ios": { + "source_files": "WebViewJavascriptBridge/*.{h,m}", + "private_header_files": "WebViewJavascriptBridge/WebViewJavascriptBridge_JS.h", + "frameworks": [ + "UIKit", + "WebKit" + ] + }, + "osx": { + "source_files": "WebViewJavascriptBridge/*.{h,m}", + "private_header_files": "WebViewJavascriptBridge/WebViewJavascriptBridge_JS.h" + }, + "frameworks": "WebKit" +} diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Manifest.lock b/Example Apps/ExampleSwiftApp-iOS/Pods/Manifest.lock new file mode 100644 index 00000000..0f348683 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Manifest.lock @@ -0,0 +1,16 @@ +PODS: + - WebViewJavascriptBridge (6.0.2) + +DEPENDENCIES: + - WebViewJavascriptBridge (from `../..`) + +EXTERNAL SOURCES: + WebViewJavascriptBridge: + :path: ../.. + +SPEC CHECKSUMS: + WebViewJavascriptBridge: 791ee0e26d1bf15efe5fb7fb9666a71a19b89d77 + +PODFILE CHECKSUM: f657cfcc5a24b7c7f0c7781719b73d4a834bc276 + +COCOAPODS: 1.1.1 diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Pods.xcodeproj/project.pbxproj b/Example Apps/ExampleSwiftApp-iOS/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 00000000..3df53a61 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,746 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1CE763074FD41F8F2481F1F218DE4A8D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81607F20092CACC1394D3DCB7D6993B0 /* Foundation.framework */; }; + 3CB3835FBA4FA17B69633D2A875158DD /* WebViewJavascriptBridge_JS.m in Sources */ = {isa = PBXBuildFile; fileRef = ECBC45CC74132CEFC65377142E782D6C /* WebViewJavascriptBridge_JS.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 4250D949ECFC5A97E1770301D77E2605 /* WKWebViewJavascriptBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 80C51525CDB583C0489D564B2B01B11A /* WKWebViewJavascriptBridge.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 45742C8C964B582FE0ADFF2E7905DFF5 /* WebViewJavascriptBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = E2A53CC2E9D7695847074947A62978CD /* WebViewJavascriptBridge.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BB0061F245D474622102084EFAB5BD2 /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = FE6B78215ECE85734B6458DD230E2364 /* WebViewJavascriptBridge.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 502A928C6ABAB459D2BA4B139DA6E1B1 /* WebViewJavascriptBridgeBase.m in Sources */ = {isa = PBXBuildFile; fileRef = FE55E03982FB6FAB2D2EA3B51B77077C /* WebViewJavascriptBridgeBase.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 64475BD96D86AB0FCCB594C527F1CAB8 /* WebViewJavascriptBridge-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 809AF8CF0188033BFA114CCE00D8B1BE /* WebViewJavascriptBridge-dummy.m */; }; + 68865B6F5C4FE0AA46A28DCAC9F4FC2A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5147AE3C7F8B063B02257EFF0EFD800 /* UIKit.framework */; }; + 8458FF2CDCD670B1FC51A7DDFD08255D /* WKWebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = CF0C2E9DF0EDC82844031C75B907FD1C /* WKWebViewJavascriptBridge.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 84B65AC46F34EA67BF48C8C3E7E71958 /* WebViewJavascriptBridge-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 8601B0C4F04E6601DF1E5B029E37AB16 /* WebViewJavascriptBridge-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 86194B24481631A6A6D0A698889045E3 /* Pods-ExampleSwiftApp-iOSTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 51187EA2FE506237A47693D319F38538 /* Pods-ExampleSwiftApp-iOSTests-dummy.m */; }; + 8F33194746E2C7D3D5BFE4E1FA5F8F11 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81607F20092CACC1394D3DCB7D6993B0 /* Foundation.framework */; }; + 902762E83E038BF12A45D29D10921D42 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81607F20092CACC1394D3DCB7D6993B0 /* Foundation.framework */; }; + 934D4692AC47E843BCD0C3B5751BC3E0 /* WebViewJavascriptBridge_JS.h in Headers */ = {isa = PBXBuildFile; fileRef = D02463846541C58A2828A6072E9B2B9F /* WebViewJavascriptBridge_JS.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 970CB101700BE9265F0267146F918345 /* WebViewJavascriptBridgeBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 57D0D1260897B04C231A6991D22E5429 /* WebViewJavascriptBridgeBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EA1C1C1CC94437B705A83C5729E9480E /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FAF4F70740F05FA34D54F1982E18E7A /* WebKit.framework */; }; + F2BD89AED3B8530725EED73659CD7F72 /* Pods-ExampleSwiftApp-iOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 221FB5C393B5465B754FAF4DC182E72C /* Pods-ExampleSwiftApp-iOS-dummy.m */; }; + F6693066686B895A8F059D886F82D6A1 /* Pods-ExampleSwiftApp-iOS-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C83E0A2774D73C8F7C5A71AE10D90669 /* Pods-ExampleSwiftApp-iOS-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FF1285970402E7D12FC2D6EBE81D223E /* Pods-ExampleSwiftApp-iOSTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = CB0DCBAEC1A0C74D1AFC55D1DA8CB0CC /* Pods-ExampleSwiftApp-iOSTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 4CFE87BDA707128AA8A6C5FC0C72AB8C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = C1D60A5C9331D2F60A106303D3494E52; + remoteInfo = WebViewJavascriptBridge; + }; + 5FFA8080C4895A871CEA5CBB57781845 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = C1D60A5C9331D2F60A106303D3494E52; + remoteInfo = WebViewJavascriptBridge; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 074E573B7C4E7956272ECDDD90007364 /* WebViewJavascriptBridge.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = WebViewJavascriptBridge.xcconfig; sourceTree = ""; }; + 11B2B8BD3820A60AFC145AD769239715 /* Pods-ExampleSwiftApp-iOSTests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ExampleSwiftApp-iOSTests-resources.sh"; sourceTree = ""; }; + 153E8B22B37A83060A1543A8C162FF14 /* Pods_ExampleSwiftApp_iOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_ExampleSwiftApp_iOSTests.framework; path = "Pods-ExampleSwiftApp-iOSTests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 16E86B5E097D5A8CE34F29BC6EC8562A /* Pods_ExampleSwiftApp_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_ExampleSwiftApp_iOS.framework; path = "Pods-ExampleSwiftApp-iOS.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E3A50278BA035C069540E5E3AB2AEE1 /* Pods-ExampleSwiftApp-iOS-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ExampleSwiftApp-iOS-frameworks.sh"; sourceTree = ""; }; + 1FAF4F70740F05FA34D54F1982E18E7A /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; }; + 221FB5C393B5465B754FAF4DC182E72C /* Pods-ExampleSwiftApp-iOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-ExampleSwiftApp-iOS-dummy.m"; sourceTree = ""; }; + 23D3E482532423C6D5312922387BEBC0 /* Pods-ExampleSwiftApp-iOSTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ExampleSwiftApp-iOSTests-frameworks.sh"; sourceTree = ""; }; + 31A437740C886407B1BD834E14857AB2 /* Pods-ExampleSwiftApp-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ExampleSwiftApp-iOS.debug.xcconfig"; sourceTree = ""; }; + 51187EA2FE506237A47693D319F38538 /* Pods-ExampleSwiftApp-iOSTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-ExampleSwiftApp-iOSTests-dummy.m"; sourceTree = ""; }; + 51711AC3868C2190C69CA4EE14609033 /* Pods-ExampleSwiftApp-iOS-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ExampleSwiftApp-iOS-acknowledgements.plist"; sourceTree = ""; }; + 57D0D1260897B04C231A6991D22E5429 /* WebViewJavascriptBridgeBase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeBase.h; sourceTree = ""; }; + 6D44F90D4EBEFA879E24602D9D112830 /* Pods-ExampleSwiftApp-iOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ExampleSwiftApp-iOSTests.release.xcconfig"; sourceTree = ""; }; + 6D8F8016ACD01541DE8081F8C58930B7 /* Pods-ExampleSwiftApp-iOSTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-ExampleSwiftApp-iOSTests-acknowledgements.markdown"; sourceTree = ""; }; + 710F90291714B9A1D4E8E2967AA7E943 /* Pods-ExampleSwiftApp-iOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ExampleSwiftApp-iOSTests.debug.xcconfig"; sourceTree = ""; }; + 7B0012B4474436C3998A7A0A253BB7FE /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 809AF8CF0188033BFA114CCE00D8B1BE /* WebViewJavascriptBridge-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "WebViewJavascriptBridge-dummy.m"; sourceTree = ""; }; + 80C51525CDB583C0489D564B2B01B11A /* WKWebViewJavascriptBridge.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = WKWebViewJavascriptBridge.h; sourceTree = ""; }; + 81607F20092CACC1394D3DCB7D6993B0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 8601B0C4F04E6601DF1E5B029E37AB16 /* WebViewJavascriptBridge-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "WebViewJavascriptBridge-umbrella.h"; sourceTree = ""; }; + 92A1209FAB40669DA320B3F83F0A3933 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 932785F7067BA34CED10E511033B8A87 /* Pods-ExampleSwiftApp-iOS-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-ExampleSwiftApp-iOS-acknowledgements.markdown"; sourceTree = ""; }; + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 9F83FE7CA7AEEB63554078FAAB16CE8A /* WebViewJavascriptBridge.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = WebViewJavascriptBridge.framework; path = WebViewJavascriptBridge.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A17E3228DC6A2FAA18E03C30E1780481 /* Pods-ExampleSwiftApp-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ExampleSwiftApp-iOS.release.xcconfig"; sourceTree = ""; }; + A3E25E1708830CCE4BAB07009465D3A0 /* WebViewJavascriptBridge-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "WebViewJavascriptBridge-prefix.pch"; sourceTree = ""; }; + A8E9C149CADB94BAF0285D8FEC5B4543 /* Pods-ExampleSwiftApp-iOS.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-ExampleSwiftApp-iOS.modulemap"; sourceTree = ""; }; + B3B2F31B7B3A2585AC20B9B1315640AF /* Pods-ExampleSwiftApp-iOSTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-ExampleSwiftApp-iOSTests.modulemap"; sourceTree = ""; }; + C249E5C9809AB24175069C00CD913083 /* Pods-ExampleSwiftApp-iOSTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ExampleSwiftApp-iOSTests-acknowledgements.plist"; sourceTree = ""; }; + C83E0A2774D73C8F7C5A71AE10D90669 /* Pods-ExampleSwiftApp-iOS-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-ExampleSwiftApp-iOS-umbrella.h"; sourceTree = ""; }; + CB0DCBAEC1A0C74D1AFC55D1DA8CB0CC /* Pods-ExampleSwiftApp-iOSTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-ExampleSwiftApp-iOSTests-umbrella.h"; sourceTree = ""; }; + CF0C2E9DF0EDC82844031C75B907FD1C /* WKWebViewJavascriptBridge.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = WKWebViewJavascriptBridge.m; sourceTree = ""; }; + D02463846541C58A2828A6072E9B2B9F /* WebViewJavascriptBridge_JS.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_JS.h; sourceTree = ""; }; + E2A53CC2E9D7695847074947A62978CD /* WebViewJavascriptBridge.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge.h; sourceTree = ""; }; + EBC2E87E1DCDC145DB442F7AC9CEBB9E /* WebViewJavascriptBridge.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = WebViewJavascriptBridge.modulemap; sourceTree = ""; }; + ECBC45CC74132CEFC65377142E782D6C /* WebViewJavascriptBridge_JS.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_JS.m; sourceTree = ""; }; + F392BCD91CC1BBCBEC3934F857C1D59C /* Pods-ExampleSwiftApp-iOS-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ExampleSwiftApp-iOS-resources.sh"; sourceTree = ""; }; + F5147AE3C7F8B063B02257EFF0EFD800 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + FE21A82064159C68F43B52C838C010B1 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FE55E03982FB6FAB2D2EA3B51B77077C /* WebViewJavascriptBridgeBase.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeBase.m; sourceTree = ""; }; + FE6B78215ECE85734B6458DD230E2364 /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 725CFEC49A26DCFA0EE64E353D657C0D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8F33194746E2C7D3D5BFE4E1FA5F8F11 /* Foundation.framework in Frameworks */, + 68865B6F5C4FE0AA46A28DCAC9F4FC2A /* UIKit.framework in Frameworks */, + EA1C1C1CC94437B705A83C5729E9480E /* WebKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 857767A96DDF1BEA80FAB0218D443372 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1CE763074FD41F8F2481F1F218DE4A8D /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 890137DFC8228A2238111729EAD6DCB2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 902762E83E038BF12A45D29D10921D42 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 122DA2E5084A4393C29BE363C764795C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6FFDF343B465C42F26242933972F7F1D /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + 24A5F2EBAAEACE0915403BD0A61B7BDB /* Development Pods */ = { + isa = PBXGroup; + children = ( + BBA310B35CA03E5C16F75EB829798B19 /* WebViewJavascriptBridge */, + ); + name = "Development Pods"; + sourceTree = ""; + }; + 5F8EB9918E764211737A00481D412C60 /* Pods-ExampleSwiftApp-iOSTests */ = { + isa = PBXGroup; + children = ( + 92A1209FAB40669DA320B3F83F0A3933 /* Info.plist */, + B3B2F31B7B3A2585AC20B9B1315640AF /* Pods-ExampleSwiftApp-iOSTests.modulemap */, + 6D8F8016ACD01541DE8081F8C58930B7 /* Pods-ExampleSwiftApp-iOSTests-acknowledgements.markdown */, + C249E5C9809AB24175069C00CD913083 /* Pods-ExampleSwiftApp-iOSTests-acknowledgements.plist */, + 51187EA2FE506237A47693D319F38538 /* Pods-ExampleSwiftApp-iOSTests-dummy.m */, + 23D3E482532423C6D5312922387BEBC0 /* Pods-ExampleSwiftApp-iOSTests-frameworks.sh */, + 11B2B8BD3820A60AFC145AD769239715 /* Pods-ExampleSwiftApp-iOSTests-resources.sh */, + CB0DCBAEC1A0C74D1AFC55D1DA8CB0CC /* Pods-ExampleSwiftApp-iOSTests-umbrella.h */, + 710F90291714B9A1D4E8E2967AA7E943 /* Pods-ExampleSwiftApp-iOSTests.debug.xcconfig */, + 6D44F90D4EBEFA879E24602D9D112830 /* Pods-ExampleSwiftApp-iOSTests.release.xcconfig */, + ); + name = "Pods-ExampleSwiftApp-iOSTests"; + path = "Target Support Files/Pods-ExampleSwiftApp-iOSTests"; + sourceTree = ""; + }; + 6FFDF343B465C42F26242933972F7F1D /* iOS */ = { + isa = PBXGroup; + children = ( + 81607F20092CACC1394D3DCB7D6993B0 /* Foundation.framework */, + F5147AE3C7F8B063B02257EFF0EFD800 /* UIKit.framework */, + 1FAF4F70740F05FA34D54F1982E18E7A /* WebKit.framework */, + ); + name = iOS; + sourceTree = ""; + }; + 73C16EEBFFA1E1F4F0EAA9E996DDADFE /* Support Files */ = { + isa = PBXGroup; + children = ( + FE21A82064159C68F43B52C838C010B1 /* Info.plist */, + EBC2E87E1DCDC145DB442F7AC9CEBB9E /* WebViewJavascriptBridge.modulemap */, + 074E573B7C4E7956272ECDDD90007364 /* WebViewJavascriptBridge.xcconfig */, + 809AF8CF0188033BFA114CCE00D8B1BE /* WebViewJavascriptBridge-dummy.m */, + A3E25E1708830CCE4BAB07009465D3A0 /* WebViewJavascriptBridge-prefix.pch */, + 8601B0C4F04E6601DF1E5B029E37AB16 /* WebViewJavascriptBridge-umbrella.h */, + ); + name = "Support Files"; + path = "Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge"; + sourceTree = ""; + }; + 78F44B0D402C2970C0507A1D9158BD94 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + DE0ED14CB65A96D71C44D7BA5782E4C8 /* Pods-ExampleSwiftApp-iOS */, + 5F8EB9918E764211737A00481D412C60 /* Pods-ExampleSwiftApp-iOSTests */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 7DB346D0F39D3F0E887471402A8071AB = { + isa = PBXGroup; + children = ( + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, + 24A5F2EBAAEACE0915403BD0A61B7BDB /* Development Pods */, + 122DA2E5084A4393C29BE363C764795C /* Frameworks */, + E6006E29B8A33BE8A154EE70CB02A7D5 /* Products */, + 78F44B0D402C2970C0507A1D9158BD94 /* Targets Support Files */, + ); + sourceTree = ""; + }; + 911475E28609F2390A280F1D8707E180 /* WebViewJavascriptBridge */ = { + isa = PBXGroup; + children = ( + E2A53CC2E9D7695847074947A62978CD /* WebViewJavascriptBridge.h */, + FE6B78215ECE85734B6458DD230E2364 /* WebViewJavascriptBridge.m */, + D02463846541C58A2828A6072E9B2B9F /* WebViewJavascriptBridge_JS.h */, + ECBC45CC74132CEFC65377142E782D6C /* WebViewJavascriptBridge_JS.m */, + 57D0D1260897B04C231A6991D22E5429 /* WebViewJavascriptBridgeBase.h */, + FE55E03982FB6FAB2D2EA3B51B77077C /* WebViewJavascriptBridgeBase.m */, + 80C51525CDB583C0489D564B2B01B11A /* WKWebViewJavascriptBridge.h */, + CF0C2E9DF0EDC82844031C75B907FD1C /* WKWebViewJavascriptBridge.m */, + ); + name = WebViewJavascriptBridge; + path = WebViewJavascriptBridge; + sourceTree = ""; + }; + BBA310B35CA03E5C16F75EB829798B19 /* WebViewJavascriptBridge */ = { + isa = PBXGroup; + children = ( + 73C16EEBFFA1E1F4F0EAA9E996DDADFE /* Support Files */, + 911475E28609F2390A280F1D8707E180 /* WebViewJavascriptBridge */, + ); + name = WebViewJavascriptBridge; + path = ../../..; + sourceTree = ""; + }; + DE0ED14CB65A96D71C44D7BA5782E4C8 /* Pods-ExampleSwiftApp-iOS */ = { + isa = PBXGroup; + children = ( + 7B0012B4474436C3998A7A0A253BB7FE /* Info.plist */, + A8E9C149CADB94BAF0285D8FEC5B4543 /* Pods-ExampleSwiftApp-iOS.modulemap */, + 932785F7067BA34CED10E511033B8A87 /* Pods-ExampleSwiftApp-iOS-acknowledgements.markdown */, + 51711AC3868C2190C69CA4EE14609033 /* Pods-ExampleSwiftApp-iOS-acknowledgements.plist */, + 221FB5C393B5465B754FAF4DC182E72C /* Pods-ExampleSwiftApp-iOS-dummy.m */, + 1E3A50278BA035C069540E5E3AB2AEE1 /* Pods-ExampleSwiftApp-iOS-frameworks.sh */, + F392BCD91CC1BBCBEC3934F857C1D59C /* Pods-ExampleSwiftApp-iOS-resources.sh */, + C83E0A2774D73C8F7C5A71AE10D90669 /* Pods-ExampleSwiftApp-iOS-umbrella.h */, + 31A437740C886407B1BD834E14857AB2 /* Pods-ExampleSwiftApp-iOS.debug.xcconfig */, + A17E3228DC6A2FAA18E03C30E1780481 /* Pods-ExampleSwiftApp-iOS.release.xcconfig */, + ); + name = "Pods-ExampleSwiftApp-iOS"; + path = "Target Support Files/Pods-ExampleSwiftApp-iOS"; + sourceTree = ""; + }; + E6006E29B8A33BE8A154EE70CB02A7D5 /* Products */ = { + isa = PBXGroup; + children = ( + 16E86B5E097D5A8CE34F29BC6EC8562A /* Pods_ExampleSwiftApp_iOS.framework */, + 153E8B22B37A83060A1543A8C162FF14 /* Pods_ExampleSwiftApp_iOSTests.framework */, + 9F83FE7CA7AEEB63554078FAAB16CE8A /* WebViewJavascriptBridge.framework */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 734E3D2EE8FCFD6CEED32749CBAB5966 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 84B65AC46F34EA67BF48C8C3E7E71958 /* WebViewJavascriptBridge-umbrella.h in Headers */, + 45742C8C964B582FE0ADFF2E7905DFF5 /* WebViewJavascriptBridge.h in Headers */, + 934D4692AC47E843BCD0C3B5751BC3E0 /* WebViewJavascriptBridge_JS.h in Headers */, + 970CB101700BE9265F0267146F918345 /* WebViewJavascriptBridgeBase.h in Headers */, + 4250D949ECFC5A97E1770301D77E2605 /* WKWebViewJavascriptBridge.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BD6C6E2FF5EA299771748CB4DED72704 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + F6693066686B895A8F059D886F82D6A1 /* Pods-ExampleSwiftApp-iOS-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D7AA88A6D68871CED7311BB22AC97F05 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + FF1285970402E7D12FC2D6EBE81D223E /* Pods-ExampleSwiftApp-iOSTests-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + A54833AA1912A64524F87E8A91967601 /* Pods-ExampleSwiftApp-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = BB29106CFF2F0230123BBB222DBAA8A3 /* Build configuration list for PBXNativeTarget "Pods-ExampleSwiftApp-iOS" */; + buildPhases = ( + A0F68E6ED45928E82301EFB65D08C62D /* Sources */, + 857767A96DDF1BEA80FAB0218D443372 /* Frameworks */, + BD6C6E2FF5EA299771748CB4DED72704 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 4C41CDA555C81C25F7F723E869937B51 /* PBXTargetDependency */, + ); + name = "Pods-ExampleSwiftApp-iOS"; + productName = "Pods-ExampleSwiftApp-iOS"; + productReference = 16E86B5E097D5A8CE34F29BC6EC8562A /* Pods_ExampleSwiftApp_iOS.framework */; + productType = "com.apple.product-type.framework"; + }; + C1D60A5C9331D2F60A106303D3494E52 /* WebViewJavascriptBridge */ = { + isa = PBXNativeTarget; + buildConfigurationList = 15283965C689D50142F65CC947E95772 /* Build configuration list for PBXNativeTarget "WebViewJavascriptBridge" */; + buildPhases = ( + 1C606BE46617D22E9EA0F278CFBBF20D /* Sources */, + 725CFEC49A26DCFA0EE64E353D657C0D /* Frameworks */, + 734E3D2EE8FCFD6CEED32749CBAB5966 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = WebViewJavascriptBridge; + productName = WebViewJavascriptBridge; + productReference = 9F83FE7CA7AEEB63554078FAAB16CE8A /* WebViewJavascriptBridge.framework */; + productType = "com.apple.product-type.framework"; + }; + E44F08A1D65BDBC2B5BCB7C942113B9D /* Pods-ExampleSwiftApp-iOSTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 71C2414272E63AF42549A85955FBFB48 /* Build configuration list for PBXNativeTarget "Pods-ExampleSwiftApp-iOSTests" */; + buildPhases = ( + 79E093A84032034699562712B5C16611 /* Sources */, + 890137DFC8228A2238111729EAD6DCB2 /* Frameworks */, + D7AA88A6D68871CED7311BB22AC97F05 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + A5ECEF2B489E810AD4D19BDA32BD0B6F /* PBXTargetDependency */, + ); + name = "Pods-ExampleSwiftApp-iOSTests"; + productName = "Pods-ExampleSwiftApp-iOSTests"; + productReference = 153E8B22B37A83060A1543A8C162FF14 /* Pods_ExampleSwiftApp_iOSTests.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0730; + LastUpgradeCheck = 0700; + }; + buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 7DB346D0F39D3F0E887471402A8071AB; + productRefGroup = E6006E29B8A33BE8A154EE70CB02A7D5 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A54833AA1912A64524F87E8A91967601 /* Pods-ExampleSwiftApp-iOS */, + E44F08A1D65BDBC2B5BCB7C942113B9D /* Pods-ExampleSwiftApp-iOSTests */, + C1D60A5C9331D2F60A106303D3494E52 /* WebViewJavascriptBridge */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 1C606BE46617D22E9EA0F278CFBBF20D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 64475BD96D86AB0FCCB594C527F1CAB8 /* WebViewJavascriptBridge-dummy.m in Sources */, + 4BB0061F245D474622102084EFAB5BD2 /* WebViewJavascriptBridge.m in Sources */, + 3CB3835FBA4FA17B69633D2A875158DD /* WebViewJavascriptBridge_JS.m in Sources */, + 502A928C6ABAB459D2BA4B139DA6E1B1 /* WebViewJavascriptBridgeBase.m in Sources */, + 8458FF2CDCD670B1FC51A7DDFD08255D /* WKWebViewJavascriptBridge.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 79E093A84032034699562712B5C16611 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 86194B24481631A6A6D0A698889045E3 /* Pods-ExampleSwiftApp-iOSTests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A0F68E6ED45928E82301EFB65D08C62D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F2BD89AED3B8530725EED73659CD7F72 /* Pods-ExampleSwiftApp-iOS-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 4C41CDA555C81C25F7F723E869937B51 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = WebViewJavascriptBridge; + target = C1D60A5C9331D2F60A106303D3494E52 /* WebViewJavascriptBridge */; + targetProxy = 5FFA8080C4895A871CEA5CBB57781845 /* PBXContainerItemProxy */; + }; + A5ECEF2B489E810AD4D19BDA32BD0B6F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = WebViewJavascriptBridge; + target = C1D60A5C9331D2F60A106303D3494E52 /* WebViewJavascriptBridge */; + targetProxy = 4CFE87BDA707128AA8A6C5FC0C72AB8C /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 038CE773516022A9EA24BAE86FEE1F0B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 074E573B7C4E7956272ECDDD90007364 /* WebViewJavascriptBridge.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/WebViewJavascriptBridge/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = WebViewJavascriptBridge; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 183F4D214A091DB4B17ACFDEC53A6378 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A17E3228DC6A2FAA18E03C30E1780481 /* Pods-ExampleSwiftApp-iOS.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-ExampleSwiftApp-iOS/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_ExampleSwiftApp_iOS; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 4DC1FAB6BB7E21E398D812098E4EA9A6 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 31A437740C886407B1BD834E14857AB2 /* Pods-ExampleSwiftApp-iOS.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-ExampleSwiftApp-iOS/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_ExampleSwiftApp_iOS; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 59B042A655B7C20CBAB90E385BF4E4C7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_REQUIRED = NO; + COPY_PHASE_STRIP = NO; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + ONLY_ACTIVE_ARCH = YES; + PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + 6D10B2247443F4A32F297F70584B2ECF /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 710F90291714B9A1D4E8E2967AA7E943 /* Pods-ExampleSwiftApp-iOSTests.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-ExampleSwiftApp-iOSTests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_ExampleSwiftApp_iOSTests; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + A595ED041DAD51092925AD1F85D81823 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 074E573B7C4E7956272ECDDD90007364 /* WebViewJavascriptBridge.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/WebViewJavascriptBridge/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = WebViewJavascriptBridge; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + B7324857C38B065FEB1EEE3105C2367A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_REQUIRED = NO; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + E53ACF0949BA7DC515874F9EBEB78B27 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6D44F90D4EBEFA879E24602D9D112830 /* Pods-ExampleSwiftApp-iOSTests.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-ExampleSwiftApp-iOSTests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_ExampleSwiftApp_iOSTests; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 15283965C689D50142F65CC947E95772 /* Build configuration list for PBXNativeTarget "WebViewJavascriptBridge" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A595ED041DAD51092925AD1F85D81823 /* Debug */, + 038CE773516022A9EA24BAE86FEE1F0B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 59B042A655B7C20CBAB90E385BF4E4C7 /* Debug */, + B7324857C38B065FEB1EEE3105C2367A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 71C2414272E63AF42549A85955FBFB48 /* Build configuration list for PBXNativeTarget "Pods-ExampleSwiftApp-iOSTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D10B2247443F4A32F297F70584B2ECF /* Debug */, + E53ACF0949BA7DC515874F9EBEB78B27 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + BB29106CFF2F0230123BBB222DBAA8A3 /* Build configuration list for PBXNativeTarget "Pods-ExampleSwiftApp-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4DC1FAB6BB7E21E398D812098E4EA9A6 /* Debug */, + 183F4D214A091DB4B17ACFDEC53A6378 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; +} diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Info.plist b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Info.plist new file mode 100644 index 00000000..2243fe6e --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-acknowledgements.markdown b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-acknowledgements.markdown new file mode 100644 index 00000000..ce5d3d20 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-acknowledgements.markdown @@ -0,0 +1,29 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## WebViewJavascriptBridge + +Copyright (c) 2011-2015 Marcus Westin, Antoine Lagadec + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-acknowledgements.plist b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-acknowledgements.plist new file mode 100644 index 00000000..ec65f732 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-acknowledgements.plist @@ -0,0 +1,61 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2011-2015 Marcus Westin, Antoine Lagadec + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + + License + MIT + Title + WebViewJavascriptBridge + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-dummy.m b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-dummy.m new file mode 100644 index 00000000..5736c16b --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_ExampleSwiftApp_iOS : NSObject +@end +@implementation PodsDummy_Pods_ExampleSwiftApp_iOS +@end diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-frameworks.sh b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-frameworks.sh new file mode 100755 index 00000000..43c5de29 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-frameworks.sh @@ -0,0 +1,91 @@ +#!/bin/sh +set -e + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # use filter instead of exclude so missing patterns dont' throw errors + echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" + /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current file + archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" + stripped="" + for arch in $archs; do + if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi +} + + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "$BUILT_PRODUCTS_DIR/WebViewJavascriptBridge/WebViewJavascriptBridge.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "$BUILT_PRODUCTS_DIR/WebViewJavascriptBridge/WebViewJavascriptBridge.framework" +fi diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-resources.sh b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-resources.sh new file mode 100755 index 00000000..25e9d377 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-resources.sh @@ -0,0 +1,96 @@ +#!/bin/sh +set -e + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; +esac + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.framework) + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" + xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +then + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "${PODS_ROOT}*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-umbrella.h b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-umbrella.h new file mode 100644 index 00000000..7d2746cd --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS-umbrella.h @@ -0,0 +1,8 @@ +#ifdef __OBJC__ +#import +#endif + + +FOUNDATION_EXPORT double Pods_ExampleSwiftApp_iOSVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_ExampleSwiftApp_iOSVersionString[]; + diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.debug.xcconfig b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.debug.xcconfig new file mode 100644 index 00000000..df30848c --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.debug.xcconfig @@ -0,0 +1,9 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/WebViewJavascriptBridge" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/WebViewJavascriptBridge/WebViewJavascriptBridge.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "WebViewJavascriptBridge" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.modulemap b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.modulemap new file mode 100644 index 00000000..4ab6cd4c --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.modulemap @@ -0,0 +1,6 @@ +framework module Pods_ExampleSwiftApp_iOS { + umbrella header "Pods-ExampleSwiftApp-iOS-umbrella.h" + + export * + module * { export * } +} diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.release.xcconfig b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.release.xcconfig new file mode 100644 index 00000000..df30848c --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOS/Pods-ExampleSwiftApp-iOS.release.xcconfig @@ -0,0 +1,9 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/WebViewJavascriptBridge" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/WebViewJavascriptBridge/WebViewJavascriptBridge.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "WebViewJavascriptBridge" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Info.plist b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Info.plist new file mode 100644 index 00000000..2243fe6e --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-acknowledgements.markdown b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-acknowledgements.markdown new file mode 100644 index 00000000..ce5d3d20 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-acknowledgements.markdown @@ -0,0 +1,29 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## WebViewJavascriptBridge + +Copyright (c) 2011-2015 Marcus Westin, Antoine Lagadec + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-acknowledgements.plist b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-acknowledgements.plist new file mode 100644 index 00000000..ec65f732 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-acknowledgements.plist @@ -0,0 +1,61 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2011-2015 Marcus Westin, Antoine Lagadec + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + + License + MIT + Title + WebViewJavascriptBridge + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-dummy.m b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-dummy.m new file mode 100644 index 00000000..ef312438 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_ExampleSwiftApp_iOSTests : NSObject +@end +@implementation PodsDummy_Pods_ExampleSwiftApp_iOSTests +@end diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-frameworks.sh b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-frameworks.sh new file mode 100755 index 00000000..43c5de29 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-frameworks.sh @@ -0,0 +1,91 @@ +#!/bin/sh +set -e + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # use filter instead of exclude so missing patterns dont' throw errors + echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" + /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current file + archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" + stripped="" + for arch in $archs; do + if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi +} + + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "$BUILT_PRODUCTS_DIR/WebViewJavascriptBridge/WebViewJavascriptBridge.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "$BUILT_PRODUCTS_DIR/WebViewJavascriptBridge/WebViewJavascriptBridge.framework" +fi diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-resources.sh b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-resources.sh new file mode 100755 index 00000000..25e9d377 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-resources.sh @@ -0,0 +1,96 @@ +#!/bin/sh +set -e + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; +esac + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.framework) + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" + xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +then + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "${PODS_ROOT}*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-umbrella.h b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-umbrella.h new file mode 100644 index 00000000..e20d8d81 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests-umbrella.h @@ -0,0 +1,8 @@ +#ifdef __OBJC__ +#import +#endif + + +FOUNDATION_EXPORT double Pods_ExampleSwiftApp_iOSTestsVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_ExampleSwiftApp_iOSTestsVersionString[]; + diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.debug.xcconfig b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.debug.xcconfig new file mode 100644 index 00000000..df30848c --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.debug.xcconfig @@ -0,0 +1,9 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/WebViewJavascriptBridge" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/WebViewJavascriptBridge/WebViewJavascriptBridge.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "WebViewJavascriptBridge" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.modulemap b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.modulemap new file mode 100644 index 00000000..1eac38ca --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.modulemap @@ -0,0 +1,6 @@ +framework module Pods_ExampleSwiftApp_iOSTests { + umbrella header "Pods-ExampleSwiftApp-iOSTests-umbrella.h" + + export * + module * { export * } +} diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.release.xcconfig b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.release.xcconfig new file mode 100644 index 00000000..df30848c --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/Pods-ExampleSwiftApp-iOSTests/Pods-ExampleSwiftApp-iOSTests.release.xcconfig @@ -0,0 +1,9 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/WebViewJavascriptBridge" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/WebViewJavascriptBridge/WebViewJavascriptBridge.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "WebViewJavascriptBridge" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/Info.plist b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/Info.plist new file mode 100644 index 00000000..69f0d0ab --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 6.0.2 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge-dummy.m b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge-dummy.m new file mode 100644 index 00000000..6c5914c8 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_WebViewJavascriptBridge : NSObject +@end +@implementation PodsDummy_WebViewJavascriptBridge +@end diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge-prefix.pch b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge-prefix.pch new file mode 100644 index 00000000..aa992a4a --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge-prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ +#import +#endif + diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge-umbrella.h b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge-umbrella.h new file mode 100644 index 00000000..41f7d8e1 --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge-umbrella.h @@ -0,0 +1,11 @@ +#ifdef __OBJC__ +#import +#endif + +#import "WebViewJavascriptBridge.h" +#import "WebViewJavascriptBridgeBase.h" +#import "WKWebViewJavascriptBridge.h" + +FOUNDATION_EXPORT double WebViewJavascriptBridgeVersionNumber; +FOUNDATION_EXPORT const unsigned char WebViewJavascriptBridgeVersionString[]; + diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge.modulemap b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge.modulemap new file mode 100644 index 00000000..e0cccd7e --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge.modulemap @@ -0,0 +1,6 @@ +framework module WebViewJavascriptBridge { + umbrella header "WebViewJavascriptBridge-umbrella.h" + + export * + module * { export * } +} diff --git a/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge.xcconfig b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge.xcconfig new file mode 100644 index 00000000..bc2e2b7a --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/Pods/Target Support Files/WebViewJavascriptBridge/WebViewJavascriptBridge.xcconfig @@ -0,0 +1,9 @@ +CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/WebViewJavascriptBridge +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" +OTHER_LDFLAGS = -framework "UIKit" -framework "WebKit" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/Example Apps/ExampleSwiftApp-iOS/echo.html b/Example Apps/ExampleSwiftApp-iOS/echo.html new file mode 100644 index 00000000..b5076d9f --- /dev/null +++ b/Example Apps/ExampleSwiftApp-iOS/echo.html @@ -0,0 +1,33 @@ + + + +

WebViewJavascriptBridgeTests - echo.html

+ + diff --git a/Makefile b/Makefile index 20d9b620..5a89b6ca 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,22 @@ test: - xcodebuild test -project Tests/WebViewJavascriptBridge.xcodeproj -scheme WebViewJavascriptBridge -destination 'platform=iOS Simulator,name=iPhone 4s' + xcodebuild test -project Tests/WebViewJavascriptBridge.xcodeproj -scheme WebViewJavascriptBridge \ + -destination 'platform=iOS Simulator,name=iPhone 8' + xcodebuild test -workspace Example\ Apps/ExampleSwiftApp-iOS/ExampleSwiftApp-iOS.xcworkspace -scheme ExampleSwiftApp-iOS \ + -destination 'platform=iOS Simulator,name=iPhone 8' + +test-many: + xcodebuild test -project Tests/WebViewJavascriptBridge.xcodeproj -scheme WebViewJavascriptBridge \ + -destination 'platform=iOS Simulator,name=iPhone 6' \ + -destination 'platform=iOS Simulator,name=iPhone 7' \ + -destination 'platform=iOS Simulator,name=iPhone 8' + +test-circle-ci: + xcodebuild test -project Tests/WebViewJavascriptBridge.xcodeproj -scheme WebViewJavascriptBridge \ + -destination 'platform=iOS Simulator,name=iPhone 7,OS=10.3.1' \ + -destination 'platform=iOS Simulator,name=iPhone X,OS=11.0.1' + publish-pod: # pod trunk register narcvs@gmail.com 'Marcus Westin' --description='MBA/MBP-xyz' + # First, bump podspec version, then commit & create tag: `git tag -a "v5.X.Y" -m "Tag v5.X.Y" && git push --tags` pod trunk push --verbose WebViewJavascriptBridge.podspec diff --git a/README.md b/README.md index ab7af42b..fb14d2de 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,14 @@ WebViewJavascriptBridge ======================= -[![Build Status](https://travis-ci.org/marcuswestin/WebViewJavascriptBridge.svg)](https://travis-ci.org/marcuswestin/WebViewJavascriptBridge) +[![Circle CI](https://img.shields.io/circleci/project/github/marcuswestin/WebViewJavascriptBridge.svg)](https://circleci.com/gh/marcuswestin/WebViewJavascriptBridge) -An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews. +An iOS/OSX bridge for sending messages between Obj-C and JavaScript in WKWebViews, UIWebViews & WebViews. + +Migration Guide +--------------- + +When upgrading from v5.0.x to 6.0.x you will have to update the `setupWebViewJavascriptBridge` javascript snippet. See https://github.com/marcuswestin/WebViewJavascriptBridge#usage part 4). Who uses WebViewJavascriptBridge? --------------------------------- @@ -22,6 +27,8 @@ WebViewJavascriptBridge is used by a range of companies and projects. This is a - [鼎盛中华](https://itunes.apple.com/us/app/ding-sheng-zhong-hua/id537273940?mt=8) - [FRIL](https://fril.jp) - [留白·WHITE](http://liubaiapp.com) +- [BrowZine](http://thirdiron.com/browzine/) +- ... & many more! Installation (iOS & OSX) ------------------------ @@ -30,7 +37,7 @@ Installation (iOS & OSX) Add this to your [podfile](https://guides.cocoapods.org/using/getting-started.html) and run `pod install` to install: ```ruby -`pod 'WebViewJavascriptBridge', '~> 5.0'` +pod 'WebViewJavascriptBridge', '~> 6.0' ``` ### Manual installation @@ -61,7 +68,7 @@ Usage @property WebViewJavascriptBridge* bridge; ``` -2) Instantiate WebViewJavascriptBridge with a UIWebView (iOS) or WebView (OSX): +2) Instantiate WebViewJavascriptBridge with a WKWebView, UIWebView (iOS) or WebView (OSX): ```objc self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView]; @@ -74,7 +81,7 @@ self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView]; NSLog(@"ObjC Echo called with: %@", data); responseCallback(data); }]; -[self.bridge callHandler:@"JS Echo" responseCallback:^(id responseData) { +[self.bridge callHandler:@"JS Echo" data:nil responseCallback:^(id responseData) { NSLog(@"ObjC received response: %@", responseData); }]; ``` @@ -88,7 +95,7 @@ function setupWebViewJavascriptBridge(callback) { window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement('iframe'); WVJBIframe.style.display = 'none'; - WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; + WVJBIframe.src = 'https://__bridge_loaded__'; document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) } @@ -105,30 +112,24 @@ setupWebViewJavascriptBridge(function(bridge) { console.log("JS Echo called with:", data) responseCallback(data) }) - bridge.callHandler('ObjC Echo', function responseCallback(responseData) { + bridge.callHandler('ObjC Echo', {'key':'value'}, function responseCallback(responseData) { console.log("JS received response:", responseData) }) }) ``` -WKWebView Support (iOS 8+ & OS 10.10+) --------------------------------------- - -(WARNING: WKWebView still has [bugs and missing network APIs.](https://github.com/ShingoFukuyama/WKWebViewTips/blob/master/README.md) It may not be a simple drop-in replacement). +Automatic reference counting (ARC) +---------------------------------- +This library relies on ARC, so if you use ARC in you project, all works fine. +But if your project have no ARC support, be sure to do next steps: -WebViewJavascriptBridge supports [WKWebView](http://nshipster.com/wkwebkit/) for iOS 8 and OSX Yosemite. In order to use WKWebView you need to instantiate the `WKWebViewJavascriptBridge`. The rest of the `WKWebViewJavascriptBridge` API is the same as `WebViewJavascriptBridge`. +1) In your Xcode project open project settings -> 'Build Phases' -1) Import the header file: - -```objc -#import "WKWebViewJavascriptBridge.h" -``` +2) Expand 'Compile Sources' header and find all *.m files which are belongs to this library. Make attention on the 'Compiler Flags' in front of each source file in this list -2) Instantiate WKWebViewJavascriptBridge and with a WKWebView object +3) For each file add '-fobjc-arc' flag -```objc -WKWebViewJavascriptBridge* bridge = [WKWebViewJavascriptBridge bridgeForWebView:webView]; -``` +Now all WVJB files will be compiled with ARC support. Contributors & Forks -------------------- @@ -141,7 +142,7 @@ API Reference ### ObjC API -##### `[WebViewJavascriptBridge bridgeForWebView:(UIWebView/WebView*)webview` +##### `[WebViewJavascriptBridge bridgeForWebView:(WKWebVIew/UIWebView/WebView*)webview` Create a javascript bridge for the given web view. @@ -181,10 +182,17 @@ Example: }]; ``` -#### `[bridge setWebViewDelegate:UIWebViewDelegate*)webViewDelegate]` +#### `[bridge setWebViewDelegate:(id)webViewDelegate]` + +Optionally, set a `WKNavigationDelegate/UIWebViewDelegate` if you need to respond to the [web view's lifecycle events](https://developer.apple.com/reference/uikit/uiwebviewdelegate). + +##### `[bridge disableJavscriptAlertBoxSafetyTimeout]` -Optionally, set a `UIWebViewDelegate` 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). +UNSAFE. Speed up bridge message passing by disabling the setTimeout safety check. It is only safe to disable this safety check if you do not call any of the javascript popup box functions (alert, confirm, and prompt). If you call any of these functions from the bridged javascript code, the app will hang. +Example: + + [self.bridge disableJavscriptAlertBoxSafetyTimeout]; @@ -204,8 +212,8 @@ bridge.registerHandler("getCurrentPageUrl", function(data, responseCallback) { ``` -##### `bridge.callHander("handlerName", data)` -##### `bridge.callHander("handlerName", data, function responseCallback(responseData) { ... })` +##### `bridge.callHandler("handlerName", data)` +##### `bridge.callHandler("handlerName", data, function responseCallback(responseData) { ... })` Call an ObjC handler called `handlerName`. If a `responseCallback` function is given the ObjC handler can respond. @@ -217,3 +225,14 @@ bridge.callHandler("getScreenHeight", null, function(response) { alert('Screen height:' + response) }) ``` + + +##### `bridge.disableJavscriptAlertBoxSafetyTimeout()` + +Calling `bridge.disableJavscriptAlertBoxSafetyTimeout()` has the same effect as calling `[bridge disableJavscriptAlertBoxSafetyTimeout];` in ObjC. + +Example: + +```javascript +bridge.disableJavscriptAlertBoxSafetyTimeout() +``` diff --git a/Roadmap.md b/Roadmap.md index a2c1aced..00e0e353 100644 --- a/Roadmap.md +++ b/Roadmap.md @@ -1,5 +1,6 @@ Roadmap ======= +###通过使用该库可以轻松实现JS与原生交互。 Issues ------ @@ -101,4 +102,4 @@ You could also create a PR with an example in `Example Apps` with the problem yo I'll close this in the meantime since there's nothing I can do. Feel free to reopen with a repro or more information. -Cheers! \ No newline at end of file +Cheers! diff --git a/Tests/WebViewJavascriptBridge.xcodeproj/project.pbxproj b/Tests/WebViewJavascriptBridge.xcodeproj/project.pbxproj index 153bfd24..763eff7c 100644 --- a/Tests/WebViewJavascriptBridge.xcodeproj/project.pbxproj +++ b/Tests/WebViewJavascriptBridge.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 2C3E7C641C5A928700A1E322 /* WebViewJavascriptBridge_JS.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C3E7C5E1C5A928700A1E322 /* WebViewJavascriptBridge_JS.m */; }; 2C3E7C651C5A928700A1E322 /* WebViewJavascriptBridgeBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C3E7C601C5A928700A1E322 /* WebViewJavascriptBridgeBase.m */; }; 2C3E7C661C5A928700A1E322 /* WKWebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C3E7C621C5A928700A1E322 /* WKWebViewJavascriptBridge.m */; }; + 2C52B1E21E11858800517DAF /* BridgeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C52B1E11E11858800517DAF /* BridgeTests.swift */; }; 2C864FFD1C60FC8A00954B70 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C864FFC1C60FC8A00954B70 /* WebKit.framework */; }; 3D99867E1AE2A3B2001DDA2C /* echo.html in Resources */ = {isa = PBXBuildFile; fileRef = 3D99867D1AE2A3B2001DDA2C /* echo.html */; }; 3D9E5F2F1AE288E5009D1C36 /* BridgeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D9E5F2E1AE288E5009D1C36 /* BridgeTests.m */; }; @@ -40,6 +41,8 @@ 2C3E7C601C5A928700A1E322 /* WebViewJavascriptBridgeBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeBase.m; sourceTree = ""; }; 2C3E7C611C5A928700A1E322 /* WKWebViewJavascriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKWebViewJavascriptBridge.h; sourceTree = ""; }; 2C3E7C621C5A928700A1E322 /* WKWebViewJavascriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WKWebViewJavascriptBridge.m; sourceTree = ""; }; + 2C52B1E01E11858800517DAF /* WebViewJavascriptBridgeTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WebViewJavascriptBridgeTests-Bridging-Header.h"; sourceTree = ""; }; + 2C52B1E11E11858800517DAF /* BridgeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BridgeTests.swift; sourceTree = ""; }; 2C864FFC1C60FC8A00954B70 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; 3D0FE4751AE2886500BB4104 /* WebViewJavascriptBridgeTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WebViewJavascriptBridgeTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3D0FE47B1AE2886500BB4104 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -115,6 +118,8 @@ children = ( 3D0FE47A1AE2886500BB4104 /* Supporting Files */, 3D9E5F2E1AE288E5009D1C36 /* BridgeTests.m */, + 2C52B1E11E11858800517DAF /* BridgeTests.swift */, + 2C52B1E01E11858800517DAF /* WebViewJavascriptBridgeTests-Bridging-Header.h */, ); path = WebViewJavascriptBridgeTests; sourceTree = ""; @@ -200,11 +205,12 @@ 3D0FE4621AE2886400BB4104 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0900; ORGANIZATIONNAME = marcuswestin; TargetAttributes = { 3D0FE4741AE2886500BB4104 = { CreatedOnToolsVersion = 6.3; + LastSwiftMigration = 0900; TestTargetID = 3DCCF7D51AE28C2900CE7C51; }; 3DCCF7D51AE28C2900CE7C51 = { @@ -259,6 +265,7 @@ 2C3E7C661C5A928700A1E322 /* WKWebViewJavascriptBridge.m in Sources */, 3D9E5F2F1AE288E5009D1C36 /* BridgeTests.m in Sources */, 2C3E7C631C5A928700A1E322 /* WebViewJavascriptBridge.m in Sources */, + 2C52B1E21E11858800517DAF /* BridgeTests.swift in Sources */, 2C3E7C641C5A928700A1E322 /* WebViewJavascriptBridge_JS.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -291,13 +298,21 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; @@ -319,7 +334,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -334,13 +349,21 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; @@ -355,9 +378,10 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -365,11 +389,9 @@ 3D0FE4821AE2886500BB4104 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -378,6 +400,10 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "in.marcuswestin.WebViewJavascriptBridge.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "WebViewJavascriptBridgeTests/WebViewJavascriptBridgeTests-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WebViewJavascriptBridgeTestHost.app/WebViewJavascriptBridgeTestHost"; }; name = Debug; @@ -385,15 +411,16 @@ 3D0FE4831AE2886500BB4104 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = WebViewJavascriptBridgeTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "in.marcuswestin.WebViewJavascriptBridge.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "WebViewJavascriptBridgeTests/WebViewJavascriptBridgeTests-Bridging-Header.h"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WebViewJavascriptBridgeTestHost.app/WebViewJavascriptBridgeTestHost"; }; name = Release; @@ -407,6 +434,7 @@ "$(inherited)", ); INFOPLIST_FILE = WebViewJavascriptBridgeTestHost/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "in.marcuswestin.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -418,6 +446,7 @@ buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; INFOPLIST_FILE = WebViewJavascriptBridgeTestHost/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "in.marcuswestin.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/Tests/WebViewJavascriptBridge.xcodeproj/xcshareddata/xcschemes/WebViewJavascriptBridge.xcscheme b/Tests/WebViewJavascriptBridge.xcodeproj/xcshareddata/xcschemes/WebViewJavascriptBridge.xcscheme index af2a0875..0f6982c5 100644 --- a/Tests/WebViewJavascriptBridge.xcodeproj/xcshareddata/xcschemes/WebViewJavascriptBridge.xcscheme +++ b/Tests/WebViewJavascriptBridge.xcodeproj/xcshareddata/xcschemes/WebViewJavascriptBridge.xcscheme @@ -1,6 +1,6 @@ #import "WebViewJavascriptBridge.h" -#import "WKWebViewJavascriptBridge.h" #import "AppDelegate.h" static NSString *const echoHandler = @"echoHandler"; @interface BridgeTests : XCTestCase - +@end +@interface TestWebPageLoadDelegate : NSObject +@property XCTestExpectation* expectation; @end @implementation BridgeTests { UIWebView *_uiWebView; WKWebView *_wkWebView; + NSMutableArray* _retains; } - (void)setUp { [super setUp]; UIViewController *rootVC = [[(AppDelegate *)[[UIApplication sharedApplication] delegate] window] rootViewController]; - _uiWebView = [[UIWebView alloc] initWithFrame:rootVC.view.bounds]; - CGRect wkFrame = _uiWebView.frame; - wkFrame.origin.y += _uiWebView.frame.size.height; - _wkWebView = [[WKWebView alloc] initWithFrame:wkFrame]; + CGRect frame = rootVC.view.bounds; + frame.size.height /= 2; + _uiWebView = [[UIWebView alloc] initWithFrame:frame]; + _uiWebView.backgroundColor = [UIColor blueColor]; + [rootVC.view addSubview:_uiWebView]; + frame.origin.y += frame.size.height; + _wkWebView = [[WKWebView alloc] initWithFrame:frame]; + _wkWebView.backgroundColor = [UIColor redColor]; [rootVC.view addSubview:_wkWebView]; + + _retains = [NSMutableArray array]; } - (void)tearDown { @@ -40,35 +48,26 @@ - (void)tearDown { [_wkWebView removeFromSuperview]; } +- (WebViewJavascriptBridge*)bridgeForWebView:(id)webView { + WebViewJavascriptBridge* bridge = [WebViewJavascriptBridge bridgeForWebView:webView]; + [_retains addObject:bridge]; + return bridge; +} + static void loadEchoSample(id webView) { NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"echo" withExtension:@"html"]]; [(UIWebView*)webView loadRequest:request]; } -- (void)testInitialization { - [self classSpecificTestInitialization:[WebViewJavascriptBridge class] webView:_uiWebView]; - [self classSpecificTestInitialization:[WKWebViewJavascriptBridge class] webView:_wkWebView]; - [self waitForExpectationsWithTimeout:3 handler:NULL]; -} -- (void)classSpecificTestInitialization:(Class)cls webView:(id)webView { - XCTestExpectation *startup = [self expectationWithDescription:@"Startup completed"]; - WebViewJavascriptBridge *bridge = [self bridgeForCls:cls webView:webView]; - [bridge registerHandler:@"Greet" handler:^(id data, WVJBResponseCallback responseCallback) { - XCTAssertEqualObjects(data, @"Hello world"); - [startup fulfill]; - }]; - XCTAssertNotNil(bridge); - - loadEchoSample(webView); -} +const NSTimeInterval timeoutSec = 5; - (void)testEchoHandler { - [self classSpecificTestEchoHandler:[WebViewJavascriptBridge class] webView:_uiWebView]; - [self classSpecificTestEchoHandler:[WKWebViewJavascriptBridge class] webView:_wkWebView]; - [self waitForExpectationsWithTimeout:3 handler:NULL]; + [self classSpecificTestEchoHandler:_uiWebView]; + [self classSpecificTestEchoHandler:_wkWebView]; + [self waitForExpectationsWithTimeout:timeoutSec handler:NULL]; } -- (void)classSpecificTestEchoHandler:(Class)cls webView:(id)webView { - WebViewJavascriptBridge *bridge = [self bridgeForCls:cls webView:webView]; +- (void)classSpecificTestEchoHandler:(id)webView { + WebViewJavascriptBridge *bridge = [self bridgeForWebView:webView]; XCTestExpectation *callbackInvocked = [self expectationWithDescription:@"Callback invoked"]; [bridge callHandler:echoHandler data:@"testEchoHandler" responseCallback:^(id responseData) { @@ -80,12 +79,12 @@ - (void)classSpecificTestEchoHandler:(Class)cls webView:(id)webView { } - (void)testEchoHandlerAfterSetup { - [self classSpecificTestEchoHandlerAfterSetup:[WebViewJavascriptBridge class] webView:_uiWebView]; - [self classSpecificTestEchoHandlerAfterSetup:[WKWebViewJavascriptBridge class] webView:_wkWebView]; - [self waitForExpectationsWithTimeout:3 handler:NULL]; + [self classSpecificTestEchoHandlerAfterSetup:_uiWebView]; + [self classSpecificTestEchoHandlerAfterSetup:_wkWebView]; + [self waitForExpectationsWithTimeout:timeoutSec handler:NULL]; } -- (void)classSpecificTestEchoHandlerAfterSetup:(Class)cls webView:(id)webView { - WebViewJavascriptBridge *bridge = [self bridgeForCls:cls webView:webView]; +- (void)classSpecificTestEchoHandlerAfterSetup:(id)webView { + WebViewJavascriptBridge *bridge = [self bridgeForWebView:webView]; XCTestExpectation *callbackInvocked = [self expectationWithDescription:@"Callback invoked"]; loadEchoSample(webView); @@ -98,12 +97,12 @@ - (void)classSpecificTestEchoHandlerAfterSetup:(Class)cls webView:(id)webView { } - (void)testObjectEncoding { - [self classSpecificTestObjectEncoding:[WebViewJavascriptBridge class] webView:_uiWebView]; - [self classSpecificTestObjectEncoding:[WKWebViewJavascriptBridge class] webView:_wkWebView]; - [self waitForExpectationsWithTimeout:3 handler:NULL]; + [self classSpecificTestObjectEncoding:_uiWebView]; + [self classSpecificTestObjectEncoding:_wkWebView]; + [self waitForExpectationsWithTimeout:timeoutSec handler:NULL]; } -- (void)classSpecificTestObjectEncoding:(Class)cls webView:(id)webView { - WebViewJavascriptBridge *bridge = [self bridgeForCls:cls webView:webView]; +- (void)classSpecificTestObjectEncoding:(id)webView { + WebViewJavascriptBridge *bridge = [self bridgeForWebView:webView]; void (^echoObject)(id) = ^void(id object) { XCTestExpectation *callbackInvocked = [self expectationWithDescription:@"Callback invoked"]; @@ -122,12 +121,31 @@ - (void)classSpecificTestObjectEncoding:(Class)cls webView:(id)webView { } - (void)testJavascriptReceiveResponse { - [self classSpecificTestJavascriptReceiveResponse:[WebViewJavascriptBridge class] webView:_uiWebView]; - [self classSpecificTestJavascriptReceiveResponse:[WKWebViewJavascriptBridge class] webView:_wkWebView]; - [self waitForExpectationsWithTimeout:3 handler:NULL]; + [self classSpecificTestJavascriptReceiveResponse:_uiWebView]; + [self classSpecificTestJavascriptReceiveResponse:_wkWebView]; + [self waitForExpectationsWithTimeout:timeoutSec handler:NULL]; +} +- (void)classSpecificTestJavascriptReceiveResponse:(id)webView { + WebViewJavascriptBridge *bridge = [self bridgeForWebView:webView]; + loadEchoSample(webView); + XCTestExpectation *callbackInvocked = [self expectationWithDescription:@"Callback invoked"]; + [bridge registerHandler:@"objcEchoToJs" handler:^(id data, WVJBResponseCallback responseCallback) { + responseCallback(data); + }]; + [bridge callHandler:@"jsRcvResponseTest" data:nil responseCallback:^(id responseData) { + XCTAssertEqualObjects(responseData, @"Response from JS"); + [callbackInvocked fulfill]; + }]; +} + +- (void)testJavascriptReceiveResponseWithoutSafetyTimeout { + [self classSpecificTestJavascriptReceiveResponseWithoutSafetyTimeout:_uiWebView]; + [self classSpecificTestJavascriptReceiveResponseWithoutSafetyTimeout:_wkWebView]; + [self waitForExpectationsWithTimeout:timeoutSec handler:NULL]; } -- (void)classSpecificTestJavascriptReceiveResponse:(Class)cls webView:(id)webView { - WebViewJavascriptBridge *bridge = [self bridgeForCls:cls webView:webView]; +- (void)classSpecificTestJavascriptReceiveResponseWithoutSafetyTimeout:(id)webView { + WebViewJavascriptBridge *bridge = [self bridgeForWebView:webView]; + [bridge disableJavscriptAlertBoxSafetyTimeout]; loadEchoSample(webView); XCTestExpectation *callbackInvocked = [self expectationWithDescription:@"Callback invoked"]; [bridge registerHandler:@"objcEchoToJs" handler:^(id data, WVJBResponseCallback responseCallback) { @@ -139,11 +157,27 @@ - (void)classSpecificTestJavascriptReceiveResponse:(Class)cls webView:(id)webVie }]; } -- (WebViewJavascriptBridge*)bridgeForCls:(Class)cls webView:(id)webView { - if (cls == [WebViewJavascriptBridge class]) { - return [WebViewJavascriptBridge bridgeForWebView:webView]; - } else { - return (WebViewJavascriptBridge*)[WKWebViewJavascriptBridge bridgeForWebView:_wkWebView]; - } +- (void)testWebpageLoad { + [self classSpecificTestWebpageLoad:_uiWebView]; + [self classSpecificTestWebpageLoad:_wkWebView]; + [self waitForExpectationsWithTimeout:timeoutSec handler:NULL]; +} +- (void)classSpecificTestWebpageLoad:(id)webView { + WebViewJavascriptBridge* bridge = [self bridgeForWebView:webView]; + TestWebPageLoadDelegate* delegate = [TestWebPageLoadDelegate new]; + delegate.expectation = [self expectationWithDescription:@"Webpage loaded"]; + [_retains addObject:delegate]; + [bridge setWebViewDelegate:delegate]; + NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://example.com"]]; + [(UIWebView*)webView loadRequest:request]; +} +@end + +@implementation TestWebPageLoadDelegate +- (void)webViewDidFinishLoad:(UIWebView *)webView { + [self.expectation fulfill]; +} +- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { + [self.expectation fulfill]; } @end diff --git a/Tests/WebViewJavascriptBridgeTests/BridgeTests.swift b/Tests/WebViewJavascriptBridgeTests/BridgeTests.swift new file mode 100644 index 00000000..3964f6ad --- /dev/null +++ b/Tests/WebViewJavascriptBridgeTests/BridgeTests.swift @@ -0,0 +1,35 @@ +// +// BridgeTests.swift +// WebViewJavascriptBridge +// +// Created by John Marcus Westin on 12/26/16. +// Copyright © 2016 marcuswestin. All rights reserved. +// + +import XCTest + +class BridgeTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Tests/WebViewJavascriptBridgeTests/WebViewJavascriptBridgeTests-Bridging-Header.h b/Tests/WebViewJavascriptBridgeTests/WebViewJavascriptBridgeTests-Bridging-Header.h new file mode 100644 index 00000000..1b2cb5d6 --- /dev/null +++ b/Tests/WebViewJavascriptBridgeTests/WebViewJavascriptBridgeTests-Bridging-Header.h @@ -0,0 +1,4 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + diff --git a/Tests/WebViewJavascriptBridgeTests/echo.html b/Tests/WebViewJavascriptBridgeTests/echo.html index 809de438..4549722d 100644 --- a/Tests/WebViewJavascriptBridgeTests/echo.html +++ b/Tests/WebViewJavascriptBridgeTests/echo.html @@ -9,13 +9,12 @@ window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement('iframe'); WVJBIframe.style.display = 'none'; - WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; + WVJBIframe.src = 'https://__bridge_loaded__'; document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) } setupWebViewJavascriptBridge(function(bridge) { - bridge.callHandler('Greet', 'Hello world'); bridge.registerHandler('echoHandler', function(data, responseCallback) { responseCallback(data) }) diff --git a/WebViewJavascriptBridge.podspec b/WebViewJavascriptBridge.podspec index acb5c269..ee75de48 100644 --- a/WebViewJavascriptBridge.podspec +++ b/WebViewJavascriptBridge.podspec @@ -1,17 +1,19 @@ Pod::Spec.new do |s| s.name = 'WebViewJavascriptBridge' - s.version = '5.0.5' - s.summary = 'An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews.' + s.version = '6.0.3' + s.summary = 'An iOS & OSX bridge for sending messages between Obj-C/Swift and JavaScript in WKWebViews, UIWebViews & WebViews.' 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 => 'v'+s.version.to_s } - s.platforms = { :ios => "5.0", :osx => "" } - s.ios.source_files = 'WebViewJavascriptBridge/*.{h,m}' - s.osx.source_files = 'WebViewJavascriptBridge/*.{h,m}' + s.platforms = { :ios => "5.0", :osx => "" } + s.requires_arc = true + + s.ios.source_files = 'WebViewJavascriptBridge/*.{h,m}' s.ios.private_header_files = 'WebViewJavascriptBridge/WebViewJavascriptBridge_JS.h' + s.osx.source_files = 'WebViewJavascriptBridge/*.{h,m}' s.osx.private_header_files = 'WebViewJavascriptBridge/WebViewJavascriptBridge_JS.h' - s.ios.framework = 'UIKit' - s.osx.framework = 'WebKit' + + s.frameworks = 'WebKit' + s.ios.frameworks = 'UIKit', 'WebKit' end diff --git a/WebViewJavascriptBridge/WKWebViewJavascriptBridge.h b/WebViewJavascriptBridge/WKWebViewJavascriptBridge.h index 99859f00..4e3404fc 100644 --- a/WebViewJavascriptBridge/WKWebViewJavascriptBridge.h +++ b/WebViewJavascriptBridge/WKWebViewJavascriptBridge.h @@ -6,10 +6,10 @@ // #if (__MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_9 || __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_1) -#define supportsWKWebKit +#define supportsWKWebView #endif -#if defined(supportsWKWebKit ) +#if defined supportsWKWebView #import #import "WebViewJavascriptBridgeBase.h" @@ -21,12 +21,14 @@ + (void)enableLogging; - (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler; +- (void)removeHandler:(NSString*)handlerName; - (void)callHandler:(NSString*)handlerName; - (void)callHandler:(NSString*)handlerName data:(id)data; - (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback; - (void)reset; -- (void)setWebViewDelegate:(id)webViewDelegate; +- (void)setWebViewDelegate:(id)webViewDelegate; +- (void)disableJavscriptAlertBoxSafetyTimeout; @end -#endif \ No newline at end of file +#endif diff --git a/WebViewJavascriptBridge/WKWebViewJavascriptBridge.m b/WebViewJavascriptBridge/WKWebViewJavascriptBridge.m index 88679fb4..73c923db 100644 --- a/WebViewJavascriptBridge/WKWebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WKWebViewJavascriptBridge.m @@ -8,11 +8,11 @@ #import "WKWebViewJavascriptBridge.h" -#if defined(supportsWKWebKit) +#if defined supportsWKWebView @implementation WKWebViewJavascriptBridge { - WKWebView* _webView; - id _webViewDelegate; + __weak WKWebView* _webView; + __weak id _webViewDelegate; long _uniqueId; WebViewJavascriptBridgeBase *_base; } @@ -53,6 +53,10 @@ - (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler { _base.messageHandlers[handlerName] = [handler copy]; } +- (void)removeHandler:(NSString *)handlerName { + [_base.messageHandlers removeObjectForKey:handlerName]; +} + - (void)reset { [_base reset]; } @@ -61,6 +65,10 @@ - (void)setWebViewDelegate:(id)webViewDelegate { _webViewDelegate = webViewDelegate; } +- (void)disableJavscriptAlertBoxSafetyTimeout { + [_base disableJavscriptAlertBoxSafetyTimeout]; +} + /* Internals ***********/ @@ -92,8 +100,7 @@ - (void)WKFlushMessageQueue { }]; } -- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation -{ +- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { if (webView != _webView) { return; } __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; @@ -103,14 +110,35 @@ - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigat } -- (void)webView:(WKWebView *)webView -decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction -decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { +- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler { + if (webView != _webView) { return; } + + __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationResponse:decisionHandler:)]) { + [strongDelegate webView:webView decidePolicyForNavigationResponse:navigationResponse decisionHandler:decisionHandler]; + } + else { + decisionHandler(WKNavigationResponsePolicyAllow); + } +} + +- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler { + if (webView != _webView) { return; } + + __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; + if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didReceiveAuthenticationChallenge:completionHandler:)]) { + [strongDelegate webView:webView didReceiveAuthenticationChallenge:challenge completionHandler:completionHandler]; + } else { + completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); + } +} + +- (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 ([_base isCorrectProcotocolScheme:url]) { + if ([_base isWebViewJavascriptBridgeURL:url]) { if ([_base isBridgeLoadedURL:url]) { [_base injectJavascriptFile]; } else if ([_base isQueueMessageURL:url]) { @@ -119,6 +147,7 @@ - (void)webView:(WKWebView *)webView [_base logUnkownMessage:url]; } decisionHandler(WKNavigationActionPolicyCancel); + return; } if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) { @@ -138,9 +167,7 @@ - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation } -- (void)webView:(WKWebView *)webView -didFailNavigation:(WKNavigation *)navigation - withError:(NSError *)error { +- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error { if (webView != _webView) { return; } __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate; @@ -158,8 +185,7 @@ - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation } } -- (NSString*) _evaluateJavascript:(NSString*)javascriptCommand -{ +- (NSString*) _evaluateJavascript:(NSString*)javascriptCommand { [_webView evaluateJavaScript:javascriptCommand completionHandler:nil]; return NULL; } diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.h b/WebViewJavascriptBridge/WebViewJavascriptBridge.h index aff05531..1b64bb4e 100755 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.h +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.h @@ -9,8 +9,15 @@ #import #import "WebViewJavascriptBridgeBase.h" +#if (__MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_9 || __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_1) +#define supportsWKWebView +#endif + +#if defined supportsWKWebView +#import +#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 @@ -25,13 +32,19 @@ @interface WebViewJavascriptBridge : WVJB_WEBVIEW_DELEGATE_INTERFACE -+ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView; + ++ (instancetype)bridgeForWebView:(id)webView; ++ (instancetype)bridge:(id)webView; + + (void)enableLogging; + (void)setLogMaxLength:(int)length; - (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler; +- (void)removeHandler:(NSString*)handlerName; - (void)callHandler:(NSString*)handlerName; - (void)callHandler:(NSString*)handlerName data:(id)data; - (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback; -- (void)setWebViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate; +- (void)setWebViewDelegate:(id)webViewDelegate; +- (void)disableJavscriptAlertBoxSafetyTimeout; + @end diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge.m b/WebViewJavascriptBridge/WebViewJavascriptBridge.m index 20e88d4f..e74a6e24 100755 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge.m @@ -8,6 +8,10 @@ #import "WebViewJavascriptBridge.h" +#if defined(supportsWKWebView) +#import "WKWebViewJavascriptBridge.h" +#endif + #if __has_feature(objc_arc_weak) #define WVJB_WEAK __weak #else @@ -24,13 +28,29 @@ @implementation WebViewJavascriptBridge { /* API *****/ -+ (void)enableLogging { [WebViewJavascriptBridgeBase enableLogging]; } -+ (void)setLogMaxLength:(int)length { [WebViewJavascriptBridgeBase setLogMaxLength:length]; } ++ (void)enableLogging { + [WebViewJavascriptBridgeBase enableLogging]; +} ++ (void)setLogMaxLength:(int)length { + [WebViewJavascriptBridgeBase setLogMaxLength:length]; +} -+ (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView { - WebViewJavascriptBridge* bridge = [[self alloc] init]; - [bridge _platformSpecificSetup:webView]; - return bridge; ++ (instancetype)bridgeForWebView:(id)webView { + return [self bridge:webView]; +} ++ (instancetype)bridge:(id)webView { +#if defined supportsWKWebView + if ([webView isKindOfClass:[WKWebView class]]) { + return (WebViewJavascriptBridge*) [WKWebViewJavascriptBridge bridgeForWebView:webView]; + } +#endif + if ([webView isKindOfClass:[WVJB_WEBVIEW_TYPE class]]) { + WebViewJavascriptBridge* bridge = [[self alloc] init]; + [bridge _platformSpecificSetup:webView]; + return bridge; + } + [NSException raise:@"BadWebViewType" format:@"Unknown web view type."]; + return nil; } - (void)setWebViewDelegate:(WVJB_WEBVIEW_DELEGATE_TYPE*)webViewDelegate { @@ -61,6 +81,15 @@ - (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler { _base.messageHandlers[handlerName] = [handler copy]; } +- (void)removeHandler:(NSString *)handlerName { + [_base.messageHandlers removeObjectForKey:handlerName]; +} + +- (void)disableJavscriptAlertBoxSafetyTimeout { + [_base disableJavscriptAlertBoxSafetyTimeout]; +} + + /* Platform agnostic internals *****************************/ @@ -71,20 +100,17 @@ - (void)dealloc { _webViewDelegate = nil; } -- (NSString*) _evaluateJavascript:(NSString*)javascriptCommand -{ +- (NSString*) _evaluateJavascript:(NSString*)javascriptCommand { return [_webView stringByEvaluatingJavaScriptFromString:javascriptCommand]; } +#if defined WVJB_PLATFORM_OSX /* Platform specific internals: OSX **********************************/ -#if defined WVJB_PLATFORM_OSX - (void) _platformSpecificSetup:(WVJB_WEBVIEW_TYPE*)webView { _webView = webView; - _webView.policyDelegate = self; - _base = [[WebViewJavascriptBridgeBase alloc] init]; _base.delegate = self; } @@ -93,12 +119,11 @@ - (void) _platformSpecificDealloc { _webView.policyDelegate = nil; } -- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener -{ +- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { if (webView != _webView) { return; } NSURL *url = [request URL]; - if ([_base isCorrectProcotocolScheme:url]) { + if ([_base isWebViewJavascriptBridgeURL:url]) { if ([_base isBridgeLoadedURL:url]) { [_base injectJavascriptFile]; } else if ([_base isQueueMessageURL:url]) { @@ -117,9 +142,9 @@ - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary +#elif defined WVJB_PLATFORM_IOS /* Platform specific internals: iOS **********************************/ -#elif defined WVJB_PLATFORM_IOS - (void) _platformSpecificSetup:(WVJB_WEBVIEW_TYPE*)webView { _webView = webView; @@ -152,9 +177,10 @@ - (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 WVJB_WEBVIEW_DELEGATE_TYPE* strongDelegate = _webViewDelegate; - if ([_base isCorrectProcotocolScheme:url]) { + if ([_base isWebViewJavascriptBridgeURL:url]) { if ([_base isBridgeLoadedURL:url]) { [_base injectJavascriptFile]; } else if ([_base isQueueMessageURL:url]) { diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridgeBase.h b/WebViewJavascriptBridge/WebViewJavascriptBridgeBase.h index 16b23c79..54d80acc 100755 --- a/WebViewJavascriptBridge/WebViewJavascriptBridgeBase.h +++ b/WebViewJavascriptBridge/WebViewJavascriptBridgeBase.h @@ -7,9 +7,10 @@ #import -#define kCustomProtocolScheme @"wvjbscheme" -#define kQueueHasMessage @"__WVJB_QUEUE_MESSAGE__" -#define kBridgeLoaded @"__BRIDGE_LOADED__" +#define kOldProtocolScheme @"wvjbscheme" +#define kNewProtocolScheme @"https" +#define kQueueHasMessage @"__wvjb_queue_message__" +#define kBridgeLoaded @"__bridge_loaded__" typedef void (^WVJBResponseCallback)(id responseData); typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback); @@ -22,7 +23,7 @@ typedef NSDictionary WVJBMessage; @interface WebViewJavascriptBridgeBase : NSObject -@property (assign) id delegate; +@property (weak, nonatomic) id delegate; @property (strong, nonatomic) NSMutableArray* startupMessageQueue; @property (strong, nonatomic) NSMutableDictionary* responseCallbacks; @property (strong, nonatomic) NSMutableDictionary* messageHandlers; @@ -34,11 +35,12 @@ typedef NSDictionary WVJBMessage; - (void)sendData:(id)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName; - (void)flushMessageQueue:(NSString *)messageQueueString; - (void)injectJavascriptFile; -- (BOOL)isCorrectProcotocolScheme:(NSURL*)url; +- (BOOL)isWebViewJavascriptBridgeURL:(NSURL*)url; - (BOOL)isQueueMessageURL:(NSURL*)urll; - (BOOL)isBridgeLoadedURL:(NSURL*)urll; - (void)logUnkownMessage:(NSURL*)url; - (NSString *)webViewJavascriptCheckCommand; - (NSString *)webViewJavascriptFetchQueyCommand; +- (void)disableJavscriptAlertBoxSafetyTimeout; -@end \ No newline at end of file +@end diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridgeBase.m b/WebViewJavascriptBridge/WebViewJavascriptBridgeBase.m index f290a48d..3ec26ed4 100755 --- a/WebViewJavascriptBridge/WebViewJavascriptBridgeBase.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridgeBase.m @@ -10,7 +10,7 @@ #import "WebViewJavascriptBridge_JS.h" @implementation WebViewJavascriptBridgeBase { - id _webViewDelegate; + __weak id _webViewDelegate; long _uniqueId; } @@ -20,13 +20,14 @@ @implementation WebViewJavascriptBridgeBase { + (void)enableLogging { logging = true; } + (void)setLogMaxLength:(int)length { logMaxLength = length;} --(id)init { - self = [super init]; - self.messageHandlers = [NSMutableDictionary dictionary]; - self.startupMessageQueue = [NSMutableArray array]; - self.responseCallbacks = [NSMutableDictionary dictionary]; - _uniqueId = 0; - return(self); +- (id)init { + if (self = [super init]) { + self.messageHandlers = [NSMutableDictionary dictionary]; + self.startupMessageQueue = [NSMutableArray array]; + self.responseCallbacks = [NSMutableDictionary dictionary]; + _uniqueId = 0; + } + return self; } - (void)dealloc { @@ -121,38 +122,44 @@ - (void)injectJavascriptFile { } } --(BOOL)isCorrectProcotocolScheme:(NSURL*)url { - if([[url scheme] isEqualToString:kCustomProtocolScheme]){ - return YES; - } else { +- (BOOL)isWebViewJavascriptBridgeURL:(NSURL*)url { + if (![self isSchemeMatch:url]) { return NO; } + return [self isBridgeLoadedURL:url] || [self isQueueMessageURL:url]; } --(BOOL)isQueueMessageURL:(NSURL*)url { - if([[url host] isEqualToString:kQueueHasMessage]){ - return YES; - } else { - return NO; - } +- (BOOL)isSchemeMatch:(NSURL*)url { + NSString* scheme = url.scheme.lowercaseString; + return [scheme isEqualToString:kNewProtocolScheme] || [scheme isEqualToString:kOldProtocolScheme]; +} + +- (BOOL)isQueueMessageURL:(NSURL*)url { + NSString* host = url.host.lowercaseString; + return [self isSchemeMatch:url] && [host isEqualToString:kQueueHasMessage]; } --(BOOL)isBridgeLoadedURL:(NSURL*)url { - return ([[url scheme] isEqualToString:kCustomProtocolScheme] && [[url host] isEqualToString:kBridgeLoaded]); +- (BOOL)isBridgeLoadedURL:(NSURL*)url { + NSString* host = url.host.lowercaseString; + return [self isSchemeMatch:url] && [host isEqualToString:kBridgeLoaded]; } --(void)logUnkownMessage:(NSURL*)url { - NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", kCustomProtocolScheme, [url path]); +- (void)logUnkownMessage:(NSURL*)url { + NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@", [url absoluteString]); } --(NSString *)webViewJavascriptCheckCommand { +- (NSString *)webViewJavascriptCheckCommand { return @"typeof WebViewJavascriptBridge == \'object\';"; } --(NSString *)webViewJavascriptFetchQueyCommand { +- (NSString *)webViewJavascriptFetchQueyCommand { return @"WebViewJavascriptBridge._fetchQueue();"; } +- (void)disableJavscriptAlertBoxSafetyTimeout { + [self sendData:nil responseCallback:nil handlerName:@"_disableJavascriptAlertBoxSafetyTimeout"]; +} + // Private // ------------------------------------------- @@ -211,4 +218,4 @@ - (void)_log:(NSString *)action json:(id)json { } } -@end \ No newline at end of file +@end diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge_JS.h b/WebViewJavascriptBridge/WebViewJavascriptBridge_JS.h index 6cb1cb95..9c857f16 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge_JS.h +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge_JS.h @@ -1,3 +1,3 @@ #import -NSString * WebViewJavascriptBridge_js(); \ No newline at end of file +NSString * WebViewJavascriptBridge_js(void); diff --git a/WebViewJavascriptBridge/WebViewJavascriptBridge_JS.m b/WebViewJavascriptBridge/WebViewJavascriptBridge_JS.m index 3a494dd4..670a552f 100644 --- a/WebViewJavascriptBridge/WebViewJavascriptBridge_JS.m +++ b/WebViewJavascriptBridge/WebViewJavascriptBridge_JS.m @@ -19,9 +19,16 @@ if (window.WebViewJavascriptBridge) { return; } + + if (!window.onerror) { + window.onerror = function(msg, url, line) { + console.log("WebViewJavascriptBridge: ERROR:" + msg + "@" + url + ":" + line); + } + } window.WebViewJavascriptBridge = { registerHandler: registerHandler, callHandler: callHandler, + disableJavscriptAlertBoxSafetyTimeout: disableJavscriptAlertBoxSafetyTimeout, _fetchQueue: _fetchQueue, _handleMessageFromObjC: _handleMessageFromObjC }; @@ -30,11 +37,12 @@ var sendMessageQueue = []; var messageHandlers = {}; - var CUSTOM_PROTOCOL_SCHEME = 'wvjbscheme'; - var QUEUE_HAS_MESSAGE = '__WVJB_QUEUE_MESSAGE__'; + var CUSTOM_PROTOCOL_SCHEME = 'https'; + var QUEUE_HAS_MESSAGE = '__wvjb_queue_message__'; var responseCallbacks = {}; var uniqueId = 1; + var dispatchMessagesWithTimeoutSafety = true; function registerHandler(handlerName, handler) { messageHandlers[handlerName] = handler; @@ -47,6 +55,9 @@ function callHandler(handlerName, data, responseCallback) { } _doSend({ handlerName:handlerName, data:data }, responseCallback); } + function disableJavscriptAlertBoxSafetyTimeout() { + dispatchMessagesWithTimeoutSafety = false; + } function _doSend(message, responseCallback) { if (responseCallback) { @@ -65,7 +76,13 @@ function _fetchQueue() { } function _dispatchMessageFromObjC(messageJSON) { - setTimeout(function _timeoutDispatchMessageFromObjC() { + if (dispatchMessagesWithTimeoutSafety) { + setTimeout(_doDispatchMessageFromObjC); + } else { + _doDispatchMessageFromObjC(); + } + + function _doDispatchMessageFromObjC() { var message = JSON.parse(messageJSON); var messageHandler; var responseCallback; @@ -81,21 +98,18 @@ function _dispatchMessageFromObjC(messageJSON) { if (message.callbackId) { var callbackResponseId = message.callbackId; responseCallback = function(responseData) { - _doSend({ responseId:callbackResponseId, responseData:responseData }); + _doSend({ handlerName:message.handlerName, responseId:callbackResponseId, responseData:responseData }); }; } var handler = messageHandlers[message.handlerName]; - try { - handler(message.data, responseCallback); - } catch(exception) { - console.log("WebViewJavascriptBridge: WARNING: javascript handler threw.", message, exception); - } if (!handler) { console.log("WebViewJavascriptBridge: WARNING: no handler for message from ObjC:", message); + } else { + handler(message.data, responseCallback); } } - }); + } } function _handleMessageFromObjC(messageJSON) { @@ -107,6 +121,8 @@ function _handleMessageFromObjC(messageJSON) { messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE; document.documentElement.appendChild(messagingIframe); + registerHandler("_disableJavascriptAlertBoxSafetyTimeout", disableJavscriptAlertBoxSafetyTimeout); + setTimeout(_callWVJBCallbacks, 0); function _callWVJBCallbacks() { var callbacks = window.WVJBCallbacks; @@ -120,4 +136,4 @@ function _callWVJBCallbacks() { #undef __wvjb_js_func__ return preprocessorJSCode; -}; \ No newline at end of file +}; diff --git a/circle.yml b/circle.yml new file mode 100644 index 00000000..af65f786 --- /dev/null +++ b/circle.yml @@ -0,0 +1,10 @@ +machine: + xcode: + version: 9.0 +# dependencies: +# override: +# - brew install kylef/formulae/swiftenv +# - swiftenv install 3.0 +test: + override: + - make test-circle-ci