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/.gitignore b/.gitignore index 9473a5d8..1aa2a895 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,5 @@ *.mode2v3 *.perspectivev3 *.xcuserstate -project.xcworkspace/ +*.xcworkspace/ xcuserdata/ 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 a1131cf3..af90a6d3 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,92 @@ +WebViewJavascriptBridge Changelog +================================= + +Release Checklist +----------------- +- gitu-update +- Note Changelog +- Bump `WebViewJavascriptBridge.podspec` version "X.Y.Z" +- gitm-commit "vX.Y.Z" +- gitt-tag "vX.Y.Z" +- pod trunk push + +Version History +--------------- + +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. ++ Allow for calling handlers from JS with just a handler name and responseCallback function (#184). + +v5.0.3 & v5.0.4 ++ Recalled builds :) + +v5.0.2 ++ Fix bug that could cause a crash if the webview loads a new page immediately after JS sends a message. + +v5.0.1 ++ Removed `WebViewJavascriptBridge -reset`. It should never have been exposed as a public API. ++ Fixed compilation in C99 mode ++ Inline JS source code. WVJB no longer requires `WebViewJavascriptBridge.js.txt` to be included as a resource. ++ Automated testing: see `make test` ++ Added Makefile with common commands ++ Significantly simplified and improved wvjb load detection ++ Simplify API by focusing on explicitly named handlers instead of a default handler and plain `send`. + +v4.1.4 ++ Improve how WVJB handles the case when there is no ObjC handler for a message received from js. ++ If an objc handler throws and exception, let it bubble up to the webkit engine instead of catching it in WVJB. + +v4.1.3 ++ Update podspec file with tag + +v4.1.2 ++ Fix bug: webViewDidStart/FinishLoad were called twice and isLoading was always true (#86) + +v4.1.1 ++ Better JS initialization script (thank @refractalize!) ++ When passing nil to an objc response callback, replace it with [NSNull null] (becomes null in js) + +v4.1.0 ++ Allow for sending null/nil data packets ++ Drop support for JSONKit ++ Clean up internal represenation of messages + +v4.0.2 ++ Fix NSInvalidArgumentException: "attempt to insert nil object" when using shorthand -callHandler: ++ Fix sending messages including __WVJB_MESSAGE_SEPERATOR__ string + +v4.0.1 ++ Fix detection of arc_weak support + +v4.0.0 ++ Consolidate platform-specific code into a single WebViewJavascriptBridge.m/h using macros (57ee322a4c5310eadd28b28f4d8522cd54123301) ++ Bugfix: Don't make navigation decisions for webviews we don't control (254ea00267f8c1e03727885f4e1e0fd5f5c78be8) + +v3.1.0 ++ Dont inject the WVJB bridge until all requests have finished loading (61b853) ++ Add podspec file (818d49cfc) ++ Memory leaks fixed (b06988f1, 20ce1b0b) ++ New major contributor @peyton! + +v3.0.0 ++ OSX Support ++ New major contributor @oakho! + +v2.1.2 ++ Copy handler and response blocks + +v2.1.1 ++ Handle edge cases gracefully (e.g. don't crash on unknown command or unexpected response) + v2.1.0 + Remove WVJBResponse object and the notion of responding with an error. See 4ab41bb4d7. diff --git a/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj new file mode 100644 index 00000000..d08ca0ab --- /dev/null +++ b/Example Apps/ExampleApp-OSX.xcodeproj/project.pbxproj @@ -0,0 +1,363 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 0ECB01491A0EEB3A0037FF4E /* WebViewJavascriptBridgeBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0ECB01461A0EEB3A0037FF4E /* WebViewJavascriptBridgeBase.m */; }; + 0ECB014A1A0EEB3A0037FF4E /* WKWebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 0ECB01481A0EEB3A0037FF4E /* WKWebViewJavascriptBridge.m */; }; + 2C136A2517641106004C7401 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C136A2417641106004C7401 /* Cocoa.framework */; }; + 2C136A2F17641106004C7401 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A2D17641106004C7401 /* InfoPlist.strings */; }; + 2C136A3117641106004C7401 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C136A3017641106004C7401 /* main.m */; }; + 2C136A3517641106004C7401 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A3317641106004C7401 /* Credits.rtf */; }; + 2C136A3817641106004C7401 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C136A3717641106004C7401 /* AppDelegate.m */; }; + 2C136A4217641236004C7401 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C136A4117641236004C7401 /* WebKit.framework */; }; + 2C136A5A17642704004C7401 /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2C136A5917642704004C7401 /* ExampleApp.html */; }; + 2C1562C6176BA9FF00B4AE50 /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1562C4176BA9FF00B4AE50 /* WebViewJavascriptBridge.m */; }; + 2C3E7C491C5A8B8D00A1E322 /* WebViewJavascriptBridge_JS.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C3E7C481C5A8B8D00A1E322 /* WebViewJavascriptBridge_JS.m */; }; + 2CF17F5317D8AACF006E828B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CF17F5217D8AACF006E828B /* MainMenu.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0ECB01451A0EEB3A0037FF4E /* WebViewJavascriptBridgeBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeBase.h; sourceTree = ""; }; + 0ECB01461A0EEB3A0037FF4E /* WebViewJavascriptBridgeBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeBase.m; sourceTree = ""; }; + 0ECB01471A0EEB3A0037FF4E /* WKWebViewJavascriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKWebViewJavascriptBridge.h; sourceTree = ""; }; + 0ECB01481A0EEB3A0037FF4E /* WKWebViewJavascriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WKWebViewJavascriptBridge.m; sourceTree = ""; }; + 2C136A2117641106004C7401 /* ExampleApp-OSX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ExampleApp-OSX.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2C136A2417641106004C7401 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + 2C136A2717641106004C7401 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + 2C136A2817641106004C7401 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + 2C136A2917641106004C7401 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 2C136A2C17641106004C7401 /* ExampleApp-OSX-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ExampleApp-OSX-Info.plist"; sourceTree = ""; }; + 2C136A2E17641106004C7401 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 2C136A3017641106004C7401 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2C136A3217641106004C7401 /* ExampleApp-OSX-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ExampleApp-OSX-Prefix.pch"; sourceTree = ""; }; + 2C136A3417641106004C7401 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; + 2C136A3617641106004C7401 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 2C136A3717641106004C7401 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 2C136A4117641236004C7401 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + 2C136A5917642704004C7401 /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = SOURCE_ROOT; }; + 2C1562C2176BA9FF00B4AE50 /* WebViewJavascriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge.h; sourceTree = ""; }; + 2C1562C4176BA9FF00B4AE50 /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge.m; sourceTree = ""; }; + 2C3E7C471C5A8B8D00A1E322 /* WebViewJavascriptBridge_JS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_JS.h; sourceTree = ""; }; + 2C3E7C481C5A8B8D00A1E322 /* WebViewJavascriptBridge_JS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_JS.m; sourceTree = ""; }; + 2CF17F5217D8AACF006E828B /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 2C136A1E17641106004C7401 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2C136A4217641236004C7401 /* WebKit.framework in Frameworks */, + 2C136A2517641106004C7401 /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2C136A1817641106004C7401 = { + isa = PBXGroup; + children = ( + 2C136A4117641236004C7401 /* WebKit.framework */, + 2C136A2A17641106004C7401 /* ExampleApp-OSX */, + 2C136A2317641106004C7401 /* Frameworks */, + 2C136A2217641106004C7401 /* Products */, + ); + sourceTree = ""; + }; + 2C136A2217641106004C7401 /* Products */ = { + isa = PBXGroup; + children = ( + 2C136A2117641106004C7401 /* ExampleApp-OSX.app */, + ); + name = Products; + sourceTree = ""; + }; + 2C136A2317641106004C7401 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2C136A2417641106004C7401 /* Cocoa.framework */, + 2C136A2617641106004C7401 /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; + 2C136A2617641106004C7401 /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 2C136A2717641106004C7401 /* AppKit.framework */, + 2C136A2817641106004C7401 /* CoreData.framework */, + 2C136A2917641106004C7401 /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 2C136A2A17641106004C7401 /* ExampleApp-OSX */ = { + isa = PBXGroup; + children = ( + 2C136A3617641106004C7401 /* AppDelegate.h */, + 2C136A3717641106004C7401 /* AppDelegate.m */, + 2C136A5917642704004C7401 /* ExampleApp.html */, + 2CF17F5217D8AACF006E828B /* MainMenu.xib */, + 2C1562C1176BA9FF00B4AE50 /* WebViewJavascriptBridge */, + 2C136A2B17641106004C7401 /* Supporting Files */, + ); + path = "ExampleApp-OSX"; + sourceTree = ""; + }; + 2C136A2B17641106004C7401 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 2C136A2C17641106004C7401 /* ExampleApp-OSX-Info.plist */, + 2C136A2D17641106004C7401 /* InfoPlist.strings */, + 2C136A3017641106004C7401 /* main.m */, + 2C136A3217641106004C7401 /* ExampleApp-OSX-Prefix.pch */, + 2C136A3317641106004C7401 /* Credits.rtf */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 2C1562C1176BA9FF00B4AE50 /* WebViewJavascriptBridge */ = { + isa = PBXGroup; + children = ( + 2C3E7C471C5A8B8D00A1E322 /* WebViewJavascriptBridge_JS.h */, + 2C3E7C481C5A8B8D00A1E322 /* WebViewJavascriptBridge_JS.m */, + 0ECB01451A0EEB3A0037FF4E /* WebViewJavascriptBridgeBase.h */, + 0ECB01461A0EEB3A0037FF4E /* WebViewJavascriptBridgeBase.m */, + 0ECB01471A0EEB3A0037FF4E /* WKWebViewJavascriptBridge.h */, + 0ECB01481A0EEB3A0037FF4E /* WKWebViewJavascriptBridge.m */, + 2C1562C2176BA9FF00B4AE50 /* WebViewJavascriptBridge.h */, + 2C1562C4176BA9FF00B4AE50 /* WebViewJavascriptBridge.m */, + ); + name = WebViewJavascriptBridge; + path = ../../WebViewJavascriptBridge; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 2C136A2017641106004C7401 /* ExampleApp-OSX */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2C136A3E17641106004C7401 /* Build configuration list for PBXNativeTarget "ExampleApp-OSX" */; + buildPhases = ( + 2C136A1D17641106004C7401 /* Sources */, + 2C136A1E17641106004C7401 /* Frameworks */, + 2C136A1F17641106004C7401 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "ExampleApp-OSX"; + productName = "ExampleApp-OSX"; + productReference = 2C136A2117641106004C7401 /* ExampleApp-OSX.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 2C136A1917641106004C7401 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0810; + ORGANIZATIONNAME = "Marcus Westin"; + }; + buildConfigurationList = 2C136A1C17641106004C7401 /* Build configuration list for PBXProject "ExampleApp-OSX" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 2C136A1817641106004C7401; + productRefGroup = 2C136A2217641106004C7401 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2C136A2017641106004C7401 /* ExampleApp-OSX */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 2C136A1F17641106004C7401 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2C136A2F17641106004C7401 /* InfoPlist.strings in Resources */, + 2C136A3517641106004C7401 /* Credits.rtf in Resources */, + 2C136A5A17642704004C7401 /* ExampleApp.html in Resources */, + 2CF17F5317D8AACF006E828B /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2C136A1D17641106004C7401 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0ECB01491A0EEB3A0037FF4E /* WebViewJavascriptBridgeBase.m in Sources */, + 0ECB014A1A0EEB3A0037FF4E /* WKWebViewJavascriptBridge.m in Sources */, + 2C3E7C491C5A8B8D00A1E322 /* WebViewJavascriptBridge_JS.m in Sources */, + 2C136A3117641106004C7401 /* main.m in Sources */, + 2C1562C6176BA9FF00B4AE50 /* WebViewJavascriptBridge.m in Sources */, + 2C136A3817641106004C7401 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 2C136A2D17641106004C7401 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 2C136A2E17641106004C7401 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 2C136A3317641106004C7401 /* Credits.rtf */ = { + isa = PBXVariantGroup; + children = ( + 2C136A3417641106004C7401 /* en */, + ); + name = Credits.rtf; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 2C136A3C17641106004C7401 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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", + "$(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; + MACOSX_DEPLOYMENT_TARGET = 10.8; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 2C136A3D17641106004C7401 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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; + }; + name = Release; + }; + 2C136A3F17641106004C7401 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ExampleApp-OSX/ExampleApp-OSX-Prefix.pch"; + INFOPLIST_FILE = "ExampleApp-OSX/ExampleApp-OSX-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.7; + PRODUCT_BUNDLE_IDENTIFIER = "WebViewJavascriptBridge.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 2C136A4017641106004C7401 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "ExampleApp-OSX/ExampleApp-OSX-Prefix.pch"; + INFOPLIST_FILE = "ExampleApp-OSX/ExampleApp-OSX-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.7; + PRODUCT_BUNDLE_IDENTIFIER = "WebViewJavascriptBridge.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2C136A1C17641106004C7401 /* Build configuration list for PBXProject "ExampleApp-OSX" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2C136A3C17641106004C7401 /* Debug */, + 2C136A3D17641106004C7401 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2C136A3E17641106004C7401 /* Build configuration list for PBXNativeTarget "ExampleApp-OSX" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2C136A3F17641106004C7401 /* Debug */, + 2C136A4017641106004C7401 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 2C136A1917641106004C7401 /* Project object */; +} diff --git a/Example Apps/ExampleApp-OSX/AppDelegate.h b/Example Apps/ExampleApp-OSX/AppDelegate.h new file mode 100644 index 00000000..6d91daf4 --- /dev/null +++ b/Example Apps/ExampleApp-OSX/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// ExampleApp-OSX +// +// Created by Marcus Westin on 6/8/13. +// Copyright (c) 2013 Marcus Westin. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + +@property (assign) IBOutlet NSWindow *window; + +@end diff --git a/Example Apps/ExampleApp-OSX/AppDelegate.m b/Example Apps/ExampleApp-OSX/AppDelegate.m new file mode 100644 index 00000000..5677342a --- /dev/null +++ b/Example Apps/ExampleApp-OSX/AppDelegate.m @@ -0,0 +1,131 @@ +// +// AppDelegate.m +// ExampleApp-OSX +// +// Created by Marcus Westin on 6/8/13. +// Copyright (c) 2013 Marcus Westin. All rights reserved. +// + +#import "AppDelegate.h" +#import +#import "WebViewJavascriptBridge.h" + +@implementation AppDelegate { + WebView* _webView; + WKWebView *_WKWebView; + WebViewJavascriptBridge* _bridge; + WebViewJavascriptBridge* _WKBridge; + NSView* _WKWebViewWrapper; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + [self _createViews]; + [self _configureWebview]; + [self _configureWKWebview]; +} + +- (void)_configureWebview { + // Create Bridge + _bridge = [WebViewJavascriptBridge bridgeForWebView:_webView]; + + [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"testObjcCallback called: %@", data); + responseCallback(@"Response from testObjcCallback"); + }]; + + [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }]; + + // Create Buttons + NSButton *callbackButton = [[NSButton alloc] initWithFrame:NSMakeRect(5, 0, 120, 40)]; + [callbackButton setTitle:@"Call handler"]; + [callbackButton setBezelStyle:NSRoundedBezelStyle]; + [callbackButton setTarget:self]; + [callbackButton setAction:@selector(_callHandler)]; + [_webView addSubview:callbackButton]; + + NSButton *webViewToggleButton = [[NSButton alloc] initWithFrame:NSMakeRect(120, 0, 180, 40)]; + [webViewToggleButton setTitle:@"Switch to WKWebView"]; + [webViewToggleButton setBezelStyle:NSRoundedBezelStyle]; + [webViewToggleButton setTarget:self]; + [webViewToggleButton setAction:@selector(_toggleExample)]; + [_webView addSubview:webViewToggleButton]; + + + // Load Page + NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; + NSString* html = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; + NSURL *baseURL = [NSURL fileURLWithPath:htmlPath]; + [[_webView mainFrame] loadHTMLString:html baseURL: baseURL]; +} + + +- (void)_configureWKWebview { + // Create Bridge + _WKBridge = [WebViewJavascriptBridge bridgeForWebView:_WKWebView]; + + [_WKBridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"testObjcCallback called: %@", data); + responseCallback(@"Response from testObjcCallback"); + }]; + + [_WKBridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }]; + + // Create Buttons + NSButton *callbackButton = [[NSButton alloc] initWithFrame:NSMakeRect(5, 0, 120, 40)]; + [callbackButton setTitle:@"Call handler"]; + [callbackButton setBezelStyle:NSRoundedBezelStyle]; + [callbackButton setTarget:self]; + [callbackButton setAction:@selector(_WKCallHandler)]; + [_WKWebView addSubview:callbackButton]; + + NSButton *webViewToggleButton = [[NSButton alloc] initWithFrame:NSMakeRect(120, 0, 180, 40)]; + [webViewToggleButton setTitle:@"Switch to WebView"]; + [webViewToggleButton setBezelStyle:NSRoundedBezelStyle]; + [webViewToggleButton setTarget:self]; + [webViewToggleButton setAction:@selector(_toggleExample)]; + [_WKWebView addSubview:webViewToggleButton]; + + // Load Page + NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; + NSString* html = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; + NSURL *baseURL = [NSURL fileURLWithPath:htmlPath]; + [_WKWebView loadHTMLString:html baseURL:baseURL]; +} + +-(void)_toggleExample { + _WKWebView.hidden = !_WKWebView.isHidden; + _webView.hidden = !_webView.isHidden; +} + +- (void)_callHandler { + id data = @{ @"greetingFromObjC": @"Hi there, JS!" }; + [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { + NSLog(@"testJavascriptHandler responded: %@", response); + }]; +} + +- (void)_WKCallHandler { + id data = @{ @"greetingFromObjC": @"Hi there, JS!" }; + [_WKBridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { + NSLog(@"testJavascriptHandler responded: %@", response); + }]; +} + +- (void)_createViews { + NSView* contentView = _window.contentView; + // WebView + _webView = [[WebView alloc] initWithFrame:contentView.frame]; + [_webView setAutoresizingMask:(NSViewHeightSizable | NSViewWidthSizable)]; + _webView.hidden = YES; + + // WKWebView + _WKWebView = [[WKWebView alloc] initWithFrame:contentView.frame]; + [_WKWebView setAutoresizingMask:(NSViewHeightSizable | NSViewWidthSizable)]; + + [contentView addSubview:_WKWebView]; + [contentView addSubview:_webView]; +} + + +@end diff --git a/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist new file mode 100644 index 00000000..b9f1feaa --- /dev/null +++ b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + ${MACOSX_DEPLOYMENT_TARGET} + NSHumanReadableCopyright + Copyright © 2013 Marcus Westin. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch new file mode 100644 index 00000000..32daebd5 --- /dev/null +++ b/Example Apps/ExampleApp-OSX/ExampleApp-OSX-Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'ExampleApp-OSX' target in the 'ExampleApp-OSX' project +// + +#ifdef __OBJC__ + #import +#endif diff --git a/Example Apps/ExampleApp-OSX/MainMenu.xib b/Example Apps/ExampleApp-OSX/MainMenu.xib new file mode 100644 index 00000000..7dd49232 --- /dev/null +++ b/Example Apps/ExampleApp-OSX/MainMenu.xib @@ -0,0 +1,3244 @@ + + + + 1070 + 11E53 + 2844 + 1138.47 + 569.00 + + 2844 + 1810 + + + NSCustomObject + NSMenu + NSMenuItem + NSView + NSWindowTemplate + WebView + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + + + PluginDependencyRecalculationVersion + + + + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + + + ExampleApp-OSX + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + ExampleApp-OSX + + + + About ExampleApp-OSX + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Preferences… + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + Services + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide ExampleApp-OSX + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit ExampleApp-OSX + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 1048576 + 2147483647 + + + submenuAction: + + File + + + + New + n + 1048576 + 2147483647 + + + + + + Open… + o + 1048576 + 2147483647 + + + + + + Open Recent + + 1048576 + 2147483647 + + + submenuAction: + + Open Recent + + + + Clear Menu + + 1048576 + 2147483647 + + + + + _NSRecentDocumentsMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Close + w + 1048576 + 2147483647 + + + + + + Save… + s + 1048576 + 2147483647 + + + + + + Revert to Saved + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Page Setup... + P + 1179648 + 2147483647 + + + + + + + Print… + p + 1048576 + 2147483647 + + + + + + + + + Edit + + 1048576 + 2147483647 + + + submenuAction: + + Edit + + + + Undo + z + 1048576 + 2147483647 + + + + + + Redo + Z + 1179648 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Cut + x + 1048576 + 2147483647 + + + + + + Copy + c + 1048576 + 2147483647 + + + + + + Paste + v + 1048576 + 2147483647 + + + + + + Paste and Match Style + V + 1572864 + 2147483647 + + + + + + Delete + + 1048576 + 2147483647 + + + + + + Select All + a + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Find + + 1048576 + 2147483647 + + + submenuAction: + + Find + + + + Find… + f + 1048576 + 2147483647 + + + 1 + + + + Find and Replace… + f + 1572864 + 2147483647 + + + 12 + + + + Find Next + g + 1048576 + 2147483647 + + + 2 + + + + Find Previous + G + 1179648 + 2147483647 + + + 3 + + + + Use Selection for Find + e + 1048576 + 2147483647 + + + 7 + + + + Jump to Selection + j + 1048576 + 2147483647 + + + + + + + + + Spelling and Grammar + + 1048576 + 2147483647 + + + submenuAction: + + Spelling and Grammar + + + + Show Spelling and Grammar + : + 1048576 + 2147483647 + + + + + + Check Document Now + ; + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Check Spelling While Typing + + 1048576 + 2147483647 + + + + + + Check Grammar With Spelling + + 1048576 + 2147483647 + + + + + + Correct Spelling Automatically + + 2147483647 + + + + + + + + + Substitutions + + 1048576 + 2147483647 + + + submenuAction: + + Substitutions + + + + Show Substitutions + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Smart Copy/Paste + f + 1048576 + 2147483647 + + + 1 + + + + Smart Quotes + g + 1048576 + 2147483647 + + + 2 + + + + Smart Dashes + + 2147483647 + + + + + + Smart Links + G + 1179648 + 2147483647 + + + 3 + + + + Text Replacement + + 2147483647 + + + + + + + + + Transformations + + 2147483647 + + + submenuAction: + + Transformations + + + + Make Upper Case + + 2147483647 + + + + + + Make Lower Case + + 2147483647 + + + + + + Capitalize + + 2147483647 + + + + + + + + + Speech + + 1048576 + 2147483647 + + + submenuAction: + + Speech + + + + Start Speaking + + 1048576 + 2147483647 + + + + + + Stop Speaking + + 1048576 + 2147483647 + + + + + + + + + + + + Format + + 2147483647 + + + submenuAction: + + Format + + + + Font + + 2147483647 + + + submenuAction: + + Font + + + + Show Fonts + t + 1048576 + 2147483647 + + + + + + Bold + b + 1048576 + 2147483647 + + + 2 + + + + Italic + i + 1048576 + 2147483647 + + + 1 + + + + Underline + u + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Bigger + + + 1048576 + 2147483647 + + + 3 + + + + Smaller + - + 1048576 + 2147483647 + + + 4 + + + + YES + YES + + + 2147483647 + + + + + + Kern + + 2147483647 + + + submenuAction: + + Kern + + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Tighten + + 2147483647 + + + + + + Loosen + + 2147483647 + + + + + + + + + Ligatures + + 2147483647 + + + submenuAction: + + Ligatures + + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Use All + + 2147483647 + + + + + + + + + Baseline + + 2147483647 + + + submenuAction: + + Baseline + + + + Use Default + + 2147483647 + + + + + + Superscript + + 2147483647 + + + + + + Subscript + + 2147483647 + + + + + + Raise + + 2147483647 + + + + + + Lower + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Colors + C + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Copy Style + c + 1572864 + 2147483647 + + + + + + Paste Style + v + 1572864 + 2147483647 + + + + + _NSFontMenu + + + + + Text + + 2147483647 + + + submenuAction: + + Text + + + + Align Left + { + 1048576 + 2147483647 + + + + + + Center + | + 1048576 + 2147483647 + + + + + + Justify + + 2147483647 + + + + + + Align Right + } + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Writing Direction + + 2147483647 + + + submenuAction: + + Writing Direction + + + + YES + Paragraph + + 2147483647 + + + + + + CURlZmF1bHQ + + 2147483647 + + + + + + CUxlZnQgdG8gUmlnaHQ + + 2147483647 + + + + + + CVJpZ2h0IHRvIExlZnQ + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + YES + Selection + + 2147483647 + + + + + + CURlZmF1bHQ + + 2147483647 + + + + + + CUxlZnQgdG8gUmlnaHQ + + 2147483647 + + + + + + CVJpZ2h0IHRvIExlZnQ + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Ruler + + 2147483647 + + + + + + Copy Ruler + c + 1310720 + 2147483647 + + + + + + Paste Ruler + v + 1310720 + 2147483647 + + + + + + + + + + + + View + + 1048576 + 2147483647 + + + submenuAction: + + View + + + + Show Toolbar + t + 1572864 + 2147483647 + + + + + + Customize Toolbar… + + 1048576 + 2147483647 + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + Window + + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 2147483647 + + + submenuAction: + + Help + + + + ExampleApp-OSX Help + ? + 1048576 + 2147483647 + + + + + _NSHelpMenu + + + + _NSMainMenu + + + 15 + 2 + {{335, 390}, {480, 360}} + 1954021376 + ExampleApp-OSX + NSWindow + + + + + 256 + {480, 360} + + + + + {{0, 0}, {1280, 778}} + {10000000000000, 10000000000000} + YES + + + AppDelegate + + + NSFontManager + + + + 256 + + Apple HTML pasteboard type + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple URL pasteboard type + Apple Web Archive pasteboard type + NSColor pasteboard type + NSFilenamesPboardType + NSStringPboardType + NeXT RTFD pasteboard type + NeXT Rich Text Format v1.0 pasteboard type + NeXT TIFF v4.0 pasteboard type + WebURLsWithTitlesPboardType + public.png + public.url + public.url-name + + {254, 200} + + + _NS:9 + + + + + + + + + + + YES + YES + + + + + + + terminate: + + + + 449 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + delegate + + + + 495 + + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + print: + + + + 86 + + + + runPageLayout: + + + + 87 + + + + clearRecentDocuments: + + + + 127 + + + + performClose: + + + + 193 + + + + toggleContinuousSpellChecking: + + + + 222 + + + + undo: + + + + 223 + + + + copy: + + + + 224 + + + + checkSpelling: + + + + 225 + + + + paste: + + + + 226 + + + + stopSpeaking: + + + + 227 + + + + cut: + + + + 228 + + + + showGuessPanel: + + + + 230 + + + + redo: + + + + 231 + + + + selectAll: + + + + 232 + + + + startSpeaking: + + + + 233 + + + + delete: + + + + 235 + + + + performZoom: + + + + 240 + + + + performFindPanelAction: + + + + 241 + + + + centerSelectionInVisibleArea: + + + + 245 + + + + toggleGrammarChecking: + + + + 347 + + + + toggleSmartInsertDelete: + + + + 355 + + + + toggleAutomaticQuoteSubstitution: + + + + 356 + + + + toggleAutomaticLinkDetection: + + + + 357 + + + + saveDocument: + + + + 362 + + + + revertDocumentToSaved: + + + + 364 + + + + runToolbarCustomizationPalette: + + + + 365 + + + + toggleToolbarShown: + + + + 366 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + newDocument: + + + + 373 + + + + openDocument: + + + + 374 + + + + raiseBaseline: + + + + 426 + + + + lowerBaseline: + + + + 427 + + + + copyFont: + + + + 428 + + + + subscript: + + + + 429 + + + + superscript: + + + + 430 + + + + tightenKerning: + + + + 431 + + + + underline: + + + + 432 + + + + orderFrontColorPanel: + + + + 433 + + + + useAllLigatures: + + + + 434 + + + + loosenKerning: + + + + 435 + + + + pasteFont: + + + + 436 + + + + unscript: + + + + 437 + + + + useStandardKerning: + + + + 438 + + + + useStandardLigatures: + + + + 439 + + + + turnOffLigatures: + + + + 440 + + + + turnOffKerning: + + + + 441 + + + + toggleAutomaticSpellingCorrection: + + + + 456 + + + + orderFrontSubstitutionsPanel: + + + + 458 + + + + toggleAutomaticDashSubstitution: + + + + 461 + + + + toggleAutomaticTextReplacement: + + + + 463 + + + + uppercaseWord: + + + + 464 + + + + capitalizeWord: + + + + 467 + + + + lowercaseWord: + + + + 468 + + + + pasteAsPlainText: + + + + 486 + + + + performFindPanelAction: + + + + 487 + + + + performFindPanelAction: + + + + 488 + + + + performFindPanelAction: + + + + 489 + + + + showHelp: + + + + 493 + + + + alignCenter: + + + + 518 + + + + pasteRuler: + + + + 519 + + + + toggleRuler: + + + + 520 + + + + alignRight: + + + + 521 + + + + copyRuler: + + + + 522 + + + + alignJustified: + + + + 523 + + + + alignLeft: + + + + 524 + + + + makeBaseWritingDirectionNatural: + + + + 525 + + + + makeBaseWritingDirectionLeftToRight: + + + + 526 + + + + makeBaseWritingDirectionRightToLeft: + + + + 527 + + + + makeTextWritingDirectionNatural: + + + + 528 + + + + makeTextWritingDirectionLeftToRight: + + + + 529 + + + + makeTextWritingDirectionRightToLeft: + + + + 530 + + + + performFindPanelAction: + + + + 535 + + + + addFontTrait: + + + + 421 + + + + addFontTrait: + + + + 422 + + + + modifyFont: + + + + 423 + + + + orderFrontFontPanel: + + + + 424 + + + + modifyFont: + + + + 425 + + + + window + + + + 532 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + + + + + + + + + + + + 19 + + + + + + + + 56 + + + + + + + + 217 + + + + + + + + 83 + + + + + + + + 81 + + + + + + + + + + + + + + + + + 75 + + + + + 78 + + + + + 72 + + + + + 82 + + + + + 124 + + + + + + + + 77 + + + + + 73 + + + + + 79 + + + + + 112 + + + + + 74 + + + + + 125 + + + + + + + + 126 + + + + + 205 + + + + + + + + + + + + + + + + + + + + + + 202 + + + + + 198 + + + + + 207 + + + + + 214 + + + + + 199 + + + + + 203 + + + + + 197 + + + + + 206 + + + + + 215 + + + + + 218 + + + + + + + + 216 + + + + + + + + 200 + + + + + + + + + + + + + 219 + + + + + 201 + + + + + 204 + + + + + 220 + + + + + + + + + + + + + 213 + + + + + 210 + + + + + 221 + + + + + 208 + + + + + 209 + + + + + 57 + + + + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + + + 144 + + + + + 129 + + + + + 143 + + + + + 236 + + + + + 131 + + + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 24 + + + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 295 + + + + + + + + 296 + + + + + + + + + 297 + + + + + 298 + + + + + 211 + + + + + + + + 212 + + + + + + + + + 195 + + + + + 196 + + + + + 346 + + + + + 348 + + + + + + + + 349 + + + + + + + + + + + + + + 350 + + + + + 351 + + + + + 354 + + + + + 375 + + + + + + + + 376 + + + + + + + + + 377 + + + + + + + + 388 + + + + + + + + + + + + + + + + + + + + + + + 389 + + + + + 390 + + + + + 391 + + + + + 392 + + + + + 393 + + + + + 394 + + + + + 395 + + + + + 396 + + + + + 397 + + + + + + + + 398 + + + + + + + + 399 + + + + + + + + 400 + + + + + 401 + + + + + 402 + + + + + 403 + + + + + 404 + + + + + 405 + + + + + + + + + + + + 406 + + + + + 407 + + + + + 408 + + + + + 409 + + + + + 410 + + + + + 411 + + + + + + + + + + 412 + + + + + 413 + + + + + 414 + + + + + 415 + + + + + + + + + + + 416 + + + + + 417 + + + + + 418 + + + + + 419 + + + + + 420 + + + + + 450 + + + + + + + + 451 + + + + + + + + + + 452 + + + + + 453 + + + + + 454 + + + + + 457 + + + + + 459 + + + + + 460 + + + + + 462 + + + + + 465 + + + + + 466 + + + + + 485 + + + + + 490 + + + + + + + + 491 + + + + + + + + 492 + + + + + 494 + + + + + 496 + + + + + + + + 497 + + + + + + + + + + + + + + + + + 498 + + + + + 499 + + + + + 500 + + + + + 501 + + + + + 502 + + + + + 503 + + + + + + + + 504 + + + + + 505 + + + + + 506 + + + + + 507 + + + + + 508 + + + + + + + + + + + + + + + + 509 + + + + + 510 + + + + + 511 + + + + + 512 + + + + + 513 + + + + + 514 + + + + + 515 + + + + + 516 + + + + + 517 + + + + + 534 + + + + + 544 + + + + + 371 + + + + + + + + 372 + + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{380, 496}, {480, 360}} + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + 559 + + + + + AppDelegate + NSObject + + window + NSWindow + + + window + + window + NSWindow + + + + IBProjectSource + ./Classes/AppDelegate.h + + + + + 0 + IBCocoaFramework + YES + 3 + + {11, 11} + {10, 3} + + YES + + diff --git a/Example Apps/ExampleApp-OSX/en.lproj/Credits.rtf b/Example Apps/ExampleApp-OSX/en.lproj/Credits.rtf new file mode 100644 index 00000000..46576ef2 --- /dev/null +++ b/Example Apps/ExampleApp-OSX/en.lproj/Credits.rtf @@ -0,0 +1,29 @@ +{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} +{\colortbl;\red255\green255\blue255;} +\paperw9840\paperh8400 +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\b\fs24 \cf0 Engineering: +\b0 \ + Some people\ +\ + +\b Human Interface Design: +\b0 \ + Some other people\ +\ + +\b Testing: +\b0 \ + Hopefully not nobody\ +\ + +\b Documentation: +\b0 \ + Whoever\ +\ + +\b With special thanks to: +\b0 \ + Mom\ +} diff --git a/ExampleApp/en.lproj/InfoPlist.strings b/Example Apps/ExampleApp-OSX/en.lproj/InfoPlist.strings similarity index 100% rename from ExampleApp/en.lproj/InfoPlist.strings rename to Example Apps/ExampleApp-OSX/en.lproj/InfoPlist.strings diff --git a/Example Apps/ExampleApp-OSX/main.m b/Example Apps/ExampleApp-OSX/main.m new file mode 100644 index 00000000..0999e46a --- /dev/null +++ b/Example Apps/ExampleApp-OSX/main.m @@ -0,0 +1,14 @@ +// +// main.m +// ExampleApp-OSX +// +// Created by Marcus Westin on 6/8/13. +// Copyright (c) 2013 Marcus Westin. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **)argv); +} diff --git a/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj new file mode 100644 index 00000000..324a5b06 --- /dev/null +++ b/Example Apps/ExampleApp-iOS.xcodeproj/project.pbxproj @@ -0,0 +1,372 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 0E4E9D4C1A101E0B00043087 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E8082DC19EDD98700479452 /* WebKit.framework */; }; + 0E50601C1A01B442000BEEEA /* WebViewJavascriptBridgeBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E50601B1A01B442000BEEEA /* WebViewJavascriptBridgeBase.m */; }; + 0E8082DB19EDC32300479452 /* WKWebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E8082DA19EDC32300479452 /* WKWebViewJavascriptBridge.m */; }; + 0ECB01441A0EE1F20037FF4E /* ExampleWKWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0ECB01431A0EE1F20037FF4E /* ExampleWKWebViewController.m */; }; + 2C1562C0176BA63500B4AE50 /* WebViewJavascriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */; }; + 2C3E7C461C5A890A00A1E322 /* WebViewJavascriptBridge_JS.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C3E7C451C5A890A00A1E322 /* WebViewJavascriptBridge_JS.m */; }; + 2C45CA2C1884AD520002A4E2 /* ExampleUIWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C45CA2B1884AD520002A4E2 /* ExampleUIWebViewController.m */; }; + 2CA045BF17117439006DEE8B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2CA045B717117439006DEE8B /* InfoPlist.strings */; }; + 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */; }; + 2CA045C317117439006DEE8B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA045BE17117439006DEE8B /* main.m */; }; + 2CA0465C1711AC8E006DEE8B /* ExampleApp.html in Resources */ = {isa = PBXBuildFile; fileRef = 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0E50601B1A01B442000BEEEA /* WebViewJavascriptBridgeBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridgeBase.m; sourceTree = ""; }; + 0E50601D1A01B44C000BEEEA /* WebViewJavascriptBridgeBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridgeBase.h; sourceTree = ""; }; + 0E8082D919EDC32300479452 /* WKWebViewJavascriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKWebViewJavascriptBridge.h; sourceTree = ""; }; + 0E8082DA19EDC32300479452 /* WKWebViewJavascriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WKWebViewJavascriptBridge.m; sourceTree = ""; }; + 0E8082DC19EDD98700479452 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + 0ECB01421A0EE1BA0037FF4E /* ExampleWKWebViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExampleWKWebViewController.h; sourceTree = ""; }; + 0ECB01431A0EE1F20037FF4E /* ExampleWKWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleWKWebViewController.m; sourceTree = ""; }; + 2C1562A8176B9F6200B4AE50 /* WebViewJavascriptBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge.h; sourceTree = ""; }; + 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge.m; sourceTree = ""; }; + 2C3E7C441C5A890A00A1E322 /* WebViewJavascriptBridge_JS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewJavascriptBridge_JS.h; sourceTree = ""; }; + 2C3E7C451C5A890A00A1E322 /* WebViewJavascriptBridge_JS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewJavascriptBridge_JS.m; sourceTree = ""; }; + 2C45CA2A1884AD520002A4E2 /* ExampleUIWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExampleUIWebViewController.h; sourceTree = ""; }; + 2C45CA2B1884AD520002A4E2 /* ExampleUIWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleUIWebViewController.m; sourceTree = ""; }; + 2CA045B817117439006DEE8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 2CA045B917117439006DEE8B /* ExampleApp-iOS-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ExampleApp-iOS-Info.plist"; sourceTree = ""; }; + 2CA045BA17117439006DEE8B /* ExampleApp-iOS-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ExampleApp-iOS-Prefix.pch"; sourceTree = ""; }; + 2CA045BC17117439006DEE8B /* ExampleAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExampleAppDelegate.h; sourceTree = ""; }; + 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleAppDelegate.m; sourceTree = ""; }; + 2CA045BE17117439006DEE8B /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ExampleApp.html; sourceTree = SOURCE_ROOT; }; + 2CAB869A1727684300BD9ED1 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "ExampleApp-iOS/Default-568h@2x.png"; sourceTree = ""; }; + 2CEB3EBB1602563600548120 /* ExampleApp-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ExampleApp-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2CEB3EBF1602563600548120 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2CEB3EC11602563600548120 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 2CEB3EC31602563600548120 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 2CEB3EB81602563600548120 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0E4E9D4C1A101E0B00043087 /* WebKit.framework in Frameworks */, + 2CEB3EC01602563600548120 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2C1562A7176B9F5400B4AE50 /* WebViewJavascriptBridge */ = { + isa = PBXGroup; + children = ( + 2C3E7C441C5A890A00A1E322 /* WebViewJavascriptBridge_JS.h */, + 2C3E7C451C5A890A00A1E322 /* WebViewJavascriptBridge_JS.m */, + 2C1562A8176B9F6200B4AE50 /* WebViewJavascriptBridge.h */, + 2C1562A9176B9F6200B4AE50 /* WebViewJavascriptBridge.m */, + 0E8082DA19EDC32300479452 /* WKWebViewJavascriptBridge.m */, + 0E8082D919EDC32300479452 /* WKWebViewJavascriptBridge.h */, + 0E50601B1A01B442000BEEEA /* WebViewJavascriptBridgeBase.m */, + 0E50601D1A01B44C000BEEEA /* WebViewJavascriptBridgeBase.h */, + ); + name = WebViewJavascriptBridge; + path = ../../WebViewJavascriptBridge; + sourceTree = ""; + }; + 2CA045B617117439006DEE8B /* ExampleApp-iOS */ = { + isa = PBXGroup; + children = ( + 2CA0465B1711AC8D006DEE8B /* ExampleApp.html */, + 2CA045BC17117439006DEE8B /* ExampleAppDelegate.h */, + 2CA045BD17117439006DEE8B /* ExampleAppDelegate.m */, + 2C45CA2A1884AD520002A4E2 /* ExampleUIWebViewController.h */, + 2C45CA2B1884AD520002A4E2 /* ExampleUIWebViewController.m */, + 0ECB01421A0EE1BA0037FF4E /* ExampleWKWebViewController.h */, + 0ECB01431A0EE1F20037FF4E /* ExampleWKWebViewController.m */, + 2C1562A7176B9F5400B4AE50 /* WebViewJavascriptBridge */, + 2CA046211711A94E006DEE8B /* Supporting Files */, + ); + path = "ExampleApp-iOS"; + sourceTree = ""; + }; + 2CA046211711A94E006DEE8B /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 2CA045B717117439006DEE8B /* InfoPlist.strings */, + 2CA045B917117439006DEE8B /* ExampleApp-iOS-Info.plist */, + 2CA045BA17117439006DEE8B /* ExampleApp-iOS-Prefix.pch */, + 2CA045BE17117439006DEE8B /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 2CEB3EB01602563600548120 = { + isa = PBXGroup; + children = ( + 2CAB869A1727684300BD9ED1 /* Default-568h@2x.png */, + 2CA045B617117439006DEE8B /* ExampleApp-iOS */, + 2CEB3EBE1602563600548120 /* Frameworks */, + 2CEB3EBC1602563600548120 /* Products */, + 81A733051B2F9C5795D856E4 /* Pods */, + ); + sourceTree = ""; + }; + 2CEB3EBC1602563600548120 /* Products */ = { + isa = PBXGroup; + children = ( + 2CEB3EBB1602563600548120 /* ExampleApp-iOS.app */, + ); + name = Products; + sourceTree = ""; + }; + 2CEB3EBE1602563600548120 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 0E8082DC19EDD98700479452 /* WebKit.framework */, + 2CEB3EBF1602563600548120 /* UIKit.framework */, + 2CEB3EC11602563600548120 /* Foundation.framework */, + 2CEB3EC31602563600548120 /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 81A733051B2F9C5795D856E4 /* Pods */ = { + isa = PBXGroup; + children = ( + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 2CEB3EBA1602563600548120 /* ExampleApp-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2CEB3ED31602563600548120 /* Build configuration list for PBXNativeTarget "ExampleApp-iOS" */; + buildPhases = ( + 2CEB3EB71602563600548120 /* Sources */, + 2CEB3EB81602563600548120 /* Frameworks */, + 2CEB3EB91602563600548120 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "ExampleApp-iOS"; + productName = ExampleApp; + productReference = 2CEB3EBB1602563600548120 /* ExampleApp-iOS.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 2CEB3EB21602563600548120 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0810; + ORGANIZATIONNAME = "Marcus Westin"; + TargetAttributes = { + 2CEB3EBA1602563600548120 = { + LastSwiftMigration = 0820; + }; + }; + }; + buildConfigurationList = 2CEB3EB51602563600548120 /* Build configuration list for PBXProject "ExampleApp-iOS" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 2CEB3EB01602563600548120; + productRefGroup = 2CEB3EBC1602563600548120 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2CEB3EBA1602563600548120 /* ExampleApp-iOS */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 2CEB3EB91602563600548120 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2CA045BF17117439006DEE8B /* InfoPlist.strings in Resources */, + 2CA0465C1711AC8E006DEE8B /* ExampleApp.html in Resources */, + 2CAB869B1727684300BD9ED1 /* Default-568h@2x.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2CEB3EB71602563600548120 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2C3E7C461C5A890A00A1E322 /* WebViewJavascriptBridge_JS.m in Sources */, + 2C1562C0176BA63500B4AE50 /* WebViewJavascriptBridge.m in Sources */, + 0E8082DB19EDC32300479452 /* WKWebViewJavascriptBridge.m in Sources */, + 2C45CA2C1884AD520002A4E2 /* ExampleUIWebViewController.m in Sources */, + 0ECB01441A0EE1F20037FF4E /* ExampleWKWebViewController.m in Sources */, + 2CA045C217117439006DEE8B /* ExampleAppDelegate.m in Sources */, + 0E50601C1A01B442000BEEEA /* WebViewJavascriptBridgeBase.m in Sources */, + 2CA045C317117439006DEE8B /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 2CA045B717117439006DEE8B /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 2CA045B817117439006DEE8B /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 2CEB3ED11602563600548120 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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 = 8.0; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 2CEB3ED21602563600548120 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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 = 8.0; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 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 = 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; + }; + 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 = 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; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2CEB3EB51602563600548120 /* Build configuration list for PBXProject "ExampleApp-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2CEB3ED11602563600548120 /* Debug */, + 2CEB3ED21602563600548120 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2CEB3ED31602563600548120 /* Build configuration list for PBXNativeTarget "ExampleApp-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2CEB3ED41602563600548120 /* Debug */, + 2CEB3ED51602563600548120 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 2CEB3EB21602563600548120 /* Project object */; +} diff --git a/Default-568h@2x.png b/Example Apps/ExampleApp-iOS/Default-568h@2x.png similarity index 100% rename from Default-568h@2x.png rename to Example Apps/ExampleApp-iOS/Default-568h@2x.png diff --git a/ExampleApp/ExampleApp-Info.plist b/Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist similarity index 85% rename from ExampleApp/ExampleApp-Info.plist rename to Example Apps/ExampleApp-iOS/ExampleApp-iOS-Info.plist index 2e36c495..3eb70251 100644 --- a/ExampleApp/ExampleApp-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 @@ -31,8 +31,6 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight diff --git a/ExampleApp/ExampleApp-Prefix.pch b/Example Apps/ExampleApp-iOS/ExampleApp-iOS-Prefix.pch similarity index 100% rename from ExampleApp/ExampleApp-Prefix.pch rename to Example Apps/ExampleApp-iOS/ExampleApp-iOS-Prefix.pch diff --git a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h new file mode 100644 index 00000000..f59015d8 --- /dev/null +++ b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.h @@ -0,0 +1,5 @@ +#import + +@interface ExampleAppDelegate : UIResponder +@property (nonatomic) UIWindow *window; +@end diff --git a/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m new file mode 100644 index 00000000..ff9f5bef --- /dev/null +++ b/Example Apps/ExampleApp-iOS/ExampleAppDelegate.m @@ -0,0 +1,30 @@ +#import "ExampleAppDelegate.h" +#import "ExampleUIWebViewController.h" +#import "ExampleWKWebViewController.h" + +@implementation ExampleAppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + // 1. Create the UIWebView example + ExampleUIWebViewController* UIWebViewExampleController = [[ExampleUIWebViewController alloc] init]; + UIWebViewExampleController.tabBarItem.title = @"UIWebView"; + + // 2. Create the tab footer and add the UIWebView example + UITabBarController *tabBarController = [[UITabBarController alloc] init]; + [tabBarController addChildViewController:UIWebViewExampleController]; + + // 3. Create the WKWebView example for devices >= iOS 8 + if([WKWebView class]) { + ExampleWKWebViewController* WKWebViewExampleController = [[ExampleWKWebViewController alloc] init]; + WKWebViewExampleController.tabBarItem.title = @"WKWebView"; + [tabBarController addChildViewController:WKWebViewExampleController]; + } + + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.rootViewController = tabBarController; + [self.window makeKeyAndVisible]; + return YES; +} + +@end diff --git a/Example Apps/ExampleApp-iOS/ExampleUIWebViewController.h b/Example Apps/ExampleApp-iOS/ExampleUIWebViewController.h new file mode 100644 index 00000000..71364e80 --- /dev/null +++ b/Example Apps/ExampleApp-iOS/ExampleUIWebViewController.h @@ -0,0 +1,13 @@ +// +// ExampleUIWebViewController.h +// ExampleApp-iOS +// +// Created by Marcus Westin on 1/13/14. +// Copyright (c) 2014 Marcus Westin. All rights reserved. +// + +#import + +@interface ExampleUIWebViewController : UINavigationController + +@end \ No newline at end of file diff --git a/Example Apps/ExampleApp-iOS/ExampleUIWebViewController.m b/Example Apps/ExampleApp-iOS/ExampleUIWebViewController.m new file mode 100644 index 00000000..f988a014 --- /dev/null +++ b/Example Apps/ExampleApp-iOS/ExampleUIWebViewController.m @@ -0,0 +1,90 @@ +// +// ExampleUIWebViewController.m +// ExampleApp-iOS +// +// Created by Marcus Westin on 1/13/14. +// Copyright (c) 2014 Marcus Westin. All rights reserved. +// + +#import "ExampleUIWebViewController.h" +#import "WebViewJavascriptBridge.h" + +@interface ExampleUIWebViewController () +@property WebViewJavascriptBridge* bridge; +@end + +@implementation ExampleUIWebViewController + +- (void)viewWillAppear:(BOOL)animated { + if (_bridge) { return; } + + UIWebView* webView = [[UIWebView alloc] initWithFrame:self.view.bounds]; + [self.view addSubview:webView]; + + [WebViewJavascriptBridge enableLogging]; + + _bridge = [WebViewJavascriptBridge bridgeForWebView:webView]; + [_bridge setWebViewDelegate:self]; + + [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"testObjcCallback called: %@", data); + responseCallback(@"Response from testObjcCallback"); + }]; + + [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }]; + + [self renderButtons:webView]; + [self loadExamplePage:webView]; +} + +- (void)webViewDidStartLoad:(UIWebView *)webView { + NSLog(@"webViewDidStartLoad"); +} + +- (void)webViewDidFinishLoad:(UIWebView *)webView { + NSLog(@"webViewDidFinishLoad"); +} + +- (void)renderButtons:(UIWebView*)webView { + 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(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(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 { + id data = @{ @"greetingFromObjC": @"Hi there, JS!" }; + [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { + NSLog(@"testJavascriptHandler responded: %@", response); + }]; +} + +- (void)loadExamplePage:(UIWebView*)webView { + NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; + NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; + NSURL *baseURL = [NSURL fileURLWithPath:htmlPath]; + [webView loadHTMLString:appHtml baseURL:baseURL]; +} +@end diff --git a/Example Apps/ExampleApp-iOS/ExampleWKWebViewController.h b/Example Apps/ExampleApp-iOS/ExampleWKWebViewController.h new file mode 100644 index 00000000..7dd92b8e --- /dev/null +++ b/Example Apps/ExampleApp-iOS/ExampleWKWebViewController.h @@ -0,0 +1,14 @@ +// +// ExampleWKWebViewController.h +// ExampleApp-iOS +// +// Created by Marcus Westin on 1/13/14. +// Copyright (c) 2014 Marcus Westin. All rights reserved. +// + +#import +#import + +@interface ExampleWKWebViewController : UINavigationController + +@end \ No newline at end of file diff --git a/Example Apps/ExampleApp-iOS/ExampleWKWebViewController.m b/Example Apps/ExampleApp-iOS/ExampleWKWebViewController.m new file mode 100644 index 00000000..f9d4ac79 --- /dev/null +++ b/Example Apps/ExampleApp-iOS/ExampleWKWebViewController.m @@ -0,0 +1,80 @@ +// +// ExampleWKWebViewController.m +// ExampleApp-iOS +// +// Created by Marcus Westin on 1/13/14. +// Copyright (c) 2014 Marcus Westin. All rights reserved. +// + +#import "ExampleWKWebViewController.h" +#import "WebViewJavascriptBridge.h" + +@interface ExampleWKWebViewController () + +@property WebViewJavascriptBridge* bridge; + +@end + +@implementation ExampleWKWebViewController + +- (void)viewWillAppear:(BOOL)animated { + if (_bridge) { return; } + + WKWebView* webView = [[NSClassFromString(@"WKWebView") alloc] initWithFrame:self.view.bounds]; + webView.navigationDelegate = self; + [self.view addSubview:webView]; + [WebViewJavascriptBridge enableLogging]; + _bridge = [WebViewJavascriptBridge bridgeForWebView:webView]; + [_bridge setWebViewDelegate:self]; + + [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { + NSLog(@"testObjcCallback called: %@", data); + responseCallback(@"Response from testObjcCallback"); + }]; + + [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }]; + + [self renderButtons:webView]; + [self loadExamplePage:webView]; +} + +- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { + NSLog(@"webViewDidStartLoad"); +} + +- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { + NSLog(@"webViewDidFinishLoad"); +} + +- (void)renderButtons:(WKWebView*)webView { + UIFont* font = [UIFont fontWithName:@"HelveticaNeue" size:12.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.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.titleLabel.font = font; +} + +- (void)callHandler:(id)sender { + id data = @{ @"greetingFromObjC": @"Hi there, JS!" }; + [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { + NSLog(@"testJavascriptHandler responded: %@", response); + }]; +} + +- (void)loadExamplePage:(WKWebView*)webView { + NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"ExampleApp" ofType:@"html"]; + NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; + NSURL *baseURL = [NSURL fileURLWithPath:htmlPath]; + [webView loadHTMLString:appHtml baseURL:baseURL]; +} +@end diff --git a/Example Apps/ExampleApp-iOS/en.lproj/InfoPlist.strings b/Example Apps/ExampleApp-iOS/en.lproj/InfoPlist.strings new file mode 100644 index 00000000..477b28ff --- /dev/null +++ b/Example Apps/ExampleApp-iOS/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/Example Apps/ExampleApp-iOS/main.m b/Example Apps/ExampleApp-iOS/main.m new file mode 100644 index 00000000..003d3a8f --- /dev/null +++ b/Example Apps/ExampleApp-iOS/main.m @@ -0,0 +1,26 @@ +#import +#import +#import +#import "ExampleAppDelegate.h" + +#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) + +int main(int argc, char * argv[]) +{ + @autoreleasepool { + // Dynamically load WebKit if iOS version >= 8 + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) { +#if TARGET_IPHONE_SIMULATOR + NSString *frameworkPath = [[NSProcessInfo processInfo] environment][@"DYLD_FALLBACK_FRAMEWORK_PATH"]; + if (frameworkPath) { + NSString *webkitLibraryPath = [NSString pathWithComponents:@[frameworkPath, @"WebKit.framework", @"WebKit"]]; + dlopen([webkitLibraryPath cStringUsingEncoding:NSUTF8StringEncoding], RTLD_LAZY); + } +#else + dlopen("/System/Library/Frameworks/WebKit.framework/WebKit", RTLD_LAZY); +#endif + } + + return UIApplicationMain(argc, argv, nil, NSStringFromClass([ExampleAppDelegate class])); + } +} \ No newline at end of file diff --git a/ExampleApp/ExampleApp.html b/Example Apps/ExampleApp.html similarity index 63% rename from ExampleApp/ExampleApp.html rename to Example Apps/ExampleApp.html index 5a12d4d2..06e7dc8a 100644 --- a/ExampleApp/ExampleApp.html +++ b/Example Apps/ExampleApp.html @@ -1,5 +1,6 @@ +