├── .gitignore ├── LICENSE ├── README.md ├── WKWebViewTest.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata └── WKWebViewTest ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets └── AppIcon.appiconset │ └── Contents.json ├── Base.lproj └── MainMenu.xib ├── Info.plist ├── WKWebView+Screenshot.h ├── WKWebView+Screenshot.m └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | #Pods/ 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Lemon Mojo - Felix Deimel e.U. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of WKWebView+Screenshot nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WKWebView+Screenshot 2 | 3 | **Update October 2, 2017**: These workarounds are **not required** anymore when targeting **10.13+** because Apple added an official API. (see [takeSnapshotWithConfiguration:completionHandler:](https://developer.apple.com/documentation/webkit/wkwebview/2873260-takesnapshotwithconfiguration)) 4 | 5 | **Update January 18, 2017**: Found another workaround by faking the presence of the WKView. 6 | 7 | **Update October 22, 2016**: This doesn't work anymore in 10.12.1 (maybe even 10.12, didn't test) because `WKView` is not exposed as a subview of `WKWebView` anymore. There is however a new API in the making that will allow taking screenshots of `WKWebView`s without using private API: https://bugs.webkit.org/show_bug.cgi?id=161450 8 | 9 | Summary 10 | ------- 11 | 12 | WKWebView+Screenshot provides simple methods that use private(!) APIs of the WebKit framework to capture a screenshot of a WKWebView running on OS X. 13 | 14 | Let me repeat the important part: This way of capturing screenshots of a WKWebView may break at any time since it's using private and undocumented APIs! It's also very likely that Apple would not allow an App that uses this method in the Mac App Store! 15 | 16 | Unfortunately, I'm not aware of any other way to capture screenshots of an WKWebView at the moment so this is probably your best bet if you're publishing outside of the App Store. 17 | 18 | ARC is currently not supported but it should be easy to convert the project. Alternatively, if your project is using ARC, you can also just disable it for WKWebView+Screenshot.m ([see this StackOverflow post](http://stackoverflow.com/questions/6646052)). 19 | 20 | Sample Usage 21 | ------------ 22 | 23 | Asynchronous method: 24 | ```objc 25 | [wkWebView captureScreenshotWithCompletionHandler:^(NSImage *screenshot) { 26 | self.imageView.image = screenshot; 27 | }]; 28 | ``` 29 | 30 | Synchronous method: 31 | ```objc 32 | dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)); 33 | self.imageView.image = [wkWebView captureScreenshotWithTimeout:timeout]; 34 | ``` 35 | 36 | License 37 | ------- 38 | 39 | [New BSD License](http://en.wikipedia.org/wiki/BSD_licenses). For the full license text, see [here](https://raw.github.com/LemonMojo/WKWebView-Screenshot/master/LICENSE). 40 | 41 | Credits 42 | ------- 43 | WKWebView+Screenshot was created by [Felix Deimel](https://github.com/LemonMojo).
44 | -------------------------------------------------------------------------------- /WKWebViewTest.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E7171BC41B281A43002DE8A7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E7171BC31B281A43002DE8A7 /* AppDelegate.m */; }; 11 | E7171BC71B281A43002DE8A7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E7171BC61B281A43002DE8A7 /* main.m */; }; 12 | E7171BC91B281A43002DE8A7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E7171BC81B281A43002DE8A7 /* Assets.xcassets */; }; 13 | E7171BCC1B281A43002DE8A7 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = E7171BCA1B281A43002DE8A7 /* MainMenu.xib */; }; 14 | E7171BD41B281A67002DE8A7 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7171BD31B281A67002DE8A7 /* WebKit.framework */; }; 15 | E7171BD61B2821F0002DE8A7 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7171BD51B2821F0002DE8A7 /* Cocoa.framework */; }; 16 | E7171BD81B2821F4002DE8A7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7171BD71B2821F4002DE8A7 /* Foundation.framework */; }; 17 | E76EA6601B876EB300AAF8E4 /* WKWebView+Screenshot.m in Sources */ = {isa = PBXBuildFile; fileRef = E76EA65F1B876EB300AAF8E4 /* WKWebView+Screenshot.m */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | E7171BBF1B281A43002DE8A7 /* WKWebViewTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WKWebViewTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | E7171BC21B281A43002DE8A7 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 23 | E7171BC31B281A43002DE8A7 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 24 | E7171BC61B281A43002DE8A7 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 25 | E7171BC81B281A43002DE8A7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 26 | E7171BCB1B281A43002DE8A7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 27 | E7171BCD1B281A43002DE8A7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 28 | E7171BD31B281A67002DE8A7 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; 29 | E7171BD51B2821F0002DE8A7 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 30 | E7171BD71B2821F4002DE8A7 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 31 | E76EA6561B875F0B00AAF8E4 /* WebCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebCore.framework; path = System/Library/Frameworks/WebKit.framework/Frameworks/WebCore.framework; sourceTree = SDKROOT; }; 32 | E76EA65E1B876EB300AAF8E4 /* WKWebView+Screenshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WKWebView+Screenshot.h"; sourceTree = ""; }; 33 | E76EA65F1B876EB300AAF8E4 /* WKWebView+Screenshot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "WKWebView+Screenshot.m"; sourceTree = ""; }; 34 | /* End PBXFileReference section */ 35 | 36 | /* Begin PBXFrameworksBuildPhase section */ 37 | E7171BBC1B281A43002DE8A7 /* Frameworks */ = { 38 | isa = PBXFrameworksBuildPhase; 39 | buildActionMask = 2147483647; 40 | files = ( 41 | E7171BD81B2821F4002DE8A7 /* Foundation.framework in Frameworks */, 42 | E7171BD61B2821F0002DE8A7 /* Cocoa.framework in Frameworks */, 43 | E7171BD41B281A67002DE8A7 /* WebKit.framework in Frameworks */, 44 | ); 45 | runOnlyForDeploymentPostprocessing = 0; 46 | }; 47 | /* End PBXFrameworksBuildPhase section */ 48 | 49 | /* Begin PBXGroup section */ 50 | E7171BB61B281A43002DE8A7 = { 51 | isa = PBXGroup; 52 | children = ( 53 | E7171BC11B281A43002DE8A7 /* WKWebViewTest */, 54 | E76EA65B1B87637F00AAF8E4 /* Frameworks */, 55 | E7171BC01B281A43002DE8A7 /* Products */, 56 | ); 57 | sourceTree = ""; 58 | }; 59 | E7171BC01B281A43002DE8A7 /* Products */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | E7171BBF1B281A43002DE8A7 /* WKWebViewTest.app */, 63 | ); 64 | name = Products; 65 | sourceTree = ""; 66 | }; 67 | E7171BC11B281A43002DE8A7 /* WKWebViewTest */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | E7171BC21B281A43002DE8A7 /* AppDelegate.h */, 71 | E7171BC31B281A43002DE8A7 /* AppDelegate.m */, 72 | E76EA65E1B876EB300AAF8E4 /* WKWebView+Screenshot.h */, 73 | E76EA65F1B876EB300AAF8E4 /* WKWebView+Screenshot.m */, 74 | E7171BC81B281A43002DE8A7 /* Assets.xcassets */, 75 | E7171BCA1B281A43002DE8A7 /* MainMenu.xib */, 76 | E7171BCD1B281A43002DE8A7 /* Info.plist */, 77 | E7171BC51B281A43002DE8A7 /* Supporting Files */, 78 | ); 79 | path = WKWebViewTest; 80 | sourceTree = ""; 81 | }; 82 | E7171BC51B281A43002DE8A7 /* Supporting Files */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | E7171BC61B281A43002DE8A7 /* main.m */, 86 | ); 87 | name = "Supporting Files"; 88 | sourceTree = ""; 89 | }; 90 | E76EA65B1B87637F00AAF8E4 /* Frameworks */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | E76EA6561B875F0B00AAF8E4 /* WebCore.framework */, 94 | E7171BD71B2821F4002DE8A7 /* Foundation.framework */, 95 | E7171BD51B2821F0002DE8A7 /* Cocoa.framework */, 96 | E7171BD31B281A67002DE8A7 /* WebKit.framework */, 97 | ); 98 | name = Frameworks; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | E7171BBE1B281A43002DE8A7 /* WKWebViewTest */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = E7171BD01B281A43002DE8A7 /* Build configuration list for PBXNativeTarget "WKWebViewTest" */; 107 | buildPhases = ( 108 | E7171BBB1B281A43002DE8A7 /* Sources */, 109 | E7171BBC1B281A43002DE8A7 /* Frameworks */, 110 | E7171BBD1B281A43002DE8A7 /* Resources */, 111 | ); 112 | buildRules = ( 113 | ); 114 | dependencies = ( 115 | ); 116 | name = WKWebViewTest; 117 | productName = WKWebViewTest; 118 | productReference = E7171BBF1B281A43002DE8A7 /* WKWebViewTest.app */; 119 | productType = "com.apple.product-type.application"; 120 | }; 121 | /* End PBXNativeTarget section */ 122 | 123 | /* Begin PBXProject section */ 124 | E7171BB71B281A43002DE8A7 /* Project object */ = { 125 | isa = PBXProject; 126 | attributes = { 127 | LastUpgradeCheck = 0700; 128 | ORGANIZATIONNAME = "Lemon Mojo"; 129 | TargetAttributes = { 130 | E7171BBE1B281A43002DE8A7 = { 131 | CreatedOnToolsVersion = 7.0; 132 | }; 133 | }; 134 | }; 135 | buildConfigurationList = E7171BBA1B281A43002DE8A7 /* Build configuration list for PBXProject "WKWebViewTest" */; 136 | compatibilityVersion = "Xcode 3.2"; 137 | developmentRegion = English; 138 | hasScannedForEncodings = 0; 139 | knownRegions = ( 140 | en, 141 | Base, 142 | ); 143 | mainGroup = E7171BB61B281A43002DE8A7; 144 | productRefGroup = E7171BC01B281A43002DE8A7 /* Products */; 145 | projectDirPath = ""; 146 | projectRoot = ""; 147 | targets = ( 148 | E7171BBE1B281A43002DE8A7 /* WKWebViewTest */, 149 | ); 150 | }; 151 | /* End PBXProject section */ 152 | 153 | /* Begin PBXResourcesBuildPhase section */ 154 | E7171BBD1B281A43002DE8A7 /* Resources */ = { 155 | isa = PBXResourcesBuildPhase; 156 | buildActionMask = 2147483647; 157 | files = ( 158 | E7171BC91B281A43002DE8A7 /* Assets.xcassets in Resources */, 159 | E7171BCC1B281A43002DE8A7 /* MainMenu.xib in Resources */, 160 | ); 161 | runOnlyForDeploymentPostprocessing = 0; 162 | }; 163 | /* End PBXResourcesBuildPhase section */ 164 | 165 | /* Begin PBXSourcesBuildPhase section */ 166 | E7171BBB1B281A43002DE8A7 /* Sources */ = { 167 | isa = PBXSourcesBuildPhase; 168 | buildActionMask = 2147483647; 169 | files = ( 170 | E76EA6601B876EB300AAF8E4 /* WKWebView+Screenshot.m in Sources */, 171 | E7171BC71B281A43002DE8A7 /* main.m in Sources */, 172 | E7171BC41B281A43002DE8A7 /* AppDelegate.m in Sources */, 173 | ); 174 | runOnlyForDeploymentPostprocessing = 0; 175 | }; 176 | /* End PBXSourcesBuildPhase section */ 177 | 178 | /* Begin PBXVariantGroup section */ 179 | E7171BCA1B281A43002DE8A7 /* MainMenu.xib */ = { 180 | isa = PBXVariantGroup; 181 | children = ( 182 | E7171BCB1B281A43002DE8A7 /* Base */, 183 | ); 184 | name = MainMenu.xib; 185 | sourceTree = ""; 186 | }; 187 | /* End PBXVariantGroup section */ 188 | 189 | /* Begin XCBuildConfiguration section */ 190 | E7171BCE1B281A43002DE8A7 /* Debug */ = { 191 | isa = XCBuildConfiguration; 192 | buildSettings = { 193 | ALWAYS_SEARCH_USER_PATHS = NO; 194 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 195 | CLANG_CXX_LIBRARY = "libc++"; 196 | CLANG_ENABLE_MODULES = YES; 197 | CLANG_ENABLE_OBJC_ARC = YES; 198 | CLANG_WARN_BOOL_CONVERSION = YES; 199 | CLANG_WARN_CONSTANT_CONVERSION = YES; 200 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 201 | CLANG_WARN_EMPTY_BODY = YES; 202 | CLANG_WARN_ENUM_CONVERSION = YES; 203 | CLANG_WARN_INT_CONVERSION = YES; 204 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 205 | CLANG_WARN_UNREACHABLE_CODE = YES; 206 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 207 | CODE_SIGN_IDENTITY = "-"; 208 | COPY_PHASE_STRIP = NO; 209 | DEBUG_INFORMATION_FORMAT = dwarf; 210 | ENABLE_STRICT_OBJC_MSGSEND = YES; 211 | ENABLE_TESTABILITY = YES; 212 | GCC_C_LANGUAGE_STANDARD = gnu99; 213 | GCC_DYNAMIC_NO_PIC = NO; 214 | GCC_NO_COMMON_BLOCKS = YES; 215 | GCC_OPTIMIZATION_LEVEL = 0; 216 | GCC_PREPROCESSOR_DEFINITIONS = ( 217 | "DEBUG=1", 218 | "$(inherited)", 219 | ); 220 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 221 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 222 | GCC_WARN_UNDECLARED_SELECTOR = YES; 223 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 224 | GCC_WARN_UNUSED_FUNCTION = YES; 225 | GCC_WARN_UNUSED_VARIABLE = YES; 226 | MACOSX_DEPLOYMENT_TARGET = 10.10; 227 | MTL_ENABLE_DEBUG_INFO = YES; 228 | ONLY_ACTIVE_ARCH = YES; 229 | SDKROOT = macosx; 230 | }; 231 | name = Debug; 232 | }; 233 | E7171BCF1B281A43002DE8A7 /* Release */ = { 234 | isa = XCBuildConfiguration; 235 | buildSettings = { 236 | ALWAYS_SEARCH_USER_PATHS = NO; 237 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 238 | CLANG_CXX_LIBRARY = "libc++"; 239 | CLANG_ENABLE_MODULES = YES; 240 | CLANG_ENABLE_OBJC_ARC = YES; 241 | CLANG_WARN_BOOL_CONVERSION = YES; 242 | CLANG_WARN_CONSTANT_CONVERSION = YES; 243 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 244 | CLANG_WARN_EMPTY_BODY = YES; 245 | CLANG_WARN_ENUM_CONVERSION = YES; 246 | CLANG_WARN_INT_CONVERSION = YES; 247 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 248 | CLANG_WARN_UNREACHABLE_CODE = YES; 249 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 250 | CODE_SIGN_IDENTITY = "-"; 251 | COPY_PHASE_STRIP = NO; 252 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 253 | ENABLE_NS_ASSERTIONS = NO; 254 | ENABLE_STRICT_OBJC_MSGSEND = YES; 255 | GCC_C_LANGUAGE_STANDARD = gnu99; 256 | GCC_NO_COMMON_BLOCKS = YES; 257 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 258 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 259 | GCC_WARN_UNDECLARED_SELECTOR = YES; 260 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 261 | GCC_WARN_UNUSED_FUNCTION = YES; 262 | GCC_WARN_UNUSED_VARIABLE = YES; 263 | MACOSX_DEPLOYMENT_TARGET = 10.10; 264 | MTL_ENABLE_DEBUG_INFO = NO; 265 | SDKROOT = macosx; 266 | }; 267 | name = Release; 268 | }; 269 | E7171BD11B281A43002DE8A7 /* Debug */ = { 270 | isa = XCBuildConfiguration; 271 | buildSettings = { 272 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 273 | CLANG_ENABLE_OBJC_ARC = NO; 274 | CLANG_MODULES_AUTOLINK = NO; 275 | COMBINE_HIDPI_IMAGES = YES; 276 | FRAMEWORK_SEARCH_PATHS = ( 277 | "$(inherited)", 278 | "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Frameworks", 279 | ); 280 | INFOPLIST_FILE = WKWebViewTest/Info.plist; 281 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 282 | OTHER_CPLUSPLUSFLAGS = ( 283 | "$(OTHER_CFLAGS)", 284 | "-stdlib=libc++", 285 | ); 286 | PRODUCT_BUNDLE_IDENTIFIER = com.lemonmojo.WKWebViewTest; 287 | PRODUCT_NAME = "$(TARGET_NAME)"; 288 | }; 289 | name = Debug; 290 | }; 291 | E7171BD21B281A43002DE8A7 /* Release */ = { 292 | isa = XCBuildConfiguration; 293 | buildSettings = { 294 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 295 | CLANG_ENABLE_OBJC_ARC = NO; 296 | CLANG_MODULES_AUTOLINK = NO; 297 | COMBINE_HIDPI_IMAGES = YES; 298 | FRAMEWORK_SEARCH_PATHS = ( 299 | "$(inherited)", 300 | "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Frameworks", 301 | ); 302 | INFOPLIST_FILE = WKWebViewTest/Info.plist; 303 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 304 | OTHER_CPLUSPLUSFLAGS = ( 305 | "$(OTHER_CFLAGS)", 306 | "-stdlib=libc++", 307 | ); 308 | PRODUCT_BUNDLE_IDENTIFIER = com.lemonmojo.WKWebViewTest; 309 | PRODUCT_NAME = "$(TARGET_NAME)"; 310 | }; 311 | name = Release; 312 | }; 313 | /* End XCBuildConfiguration section */ 314 | 315 | /* Begin XCConfigurationList section */ 316 | E7171BBA1B281A43002DE8A7 /* Build configuration list for PBXProject "WKWebViewTest" */ = { 317 | isa = XCConfigurationList; 318 | buildConfigurations = ( 319 | E7171BCE1B281A43002DE8A7 /* Debug */, 320 | E7171BCF1B281A43002DE8A7 /* Release */, 321 | ); 322 | defaultConfigurationIsVisible = 0; 323 | defaultConfigurationName = Release; 324 | }; 325 | E7171BD01B281A43002DE8A7 /* Build configuration list for PBXNativeTarget "WKWebViewTest" */ = { 326 | isa = XCConfigurationList; 327 | buildConfigurations = ( 328 | E7171BD11B281A43002DE8A7 /* Debug */, 329 | E7171BD21B281A43002DE8A7 /* Release */, 330 | ); 331 | defaultConfigurationIsVisible = 0; 332 | defaultConfigurationName = Release; 333 | }; 334 | /* End XCConfigurationList section */ 335 | }; 336 | rootObject = E7171BB71B281A43002DE8A7 /* Project object */; 337 | } 338 | -------------------------------------------------------------------------------- /WKWebViewTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WKWebViewTest/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WKWebViewTest 4 | // 5 | // Created by Felix Deimel on 10.06.15. 6 | // Copyright © Lemon Mojo - Felix Deimel e.U. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | @end -------------------------------------------------------------------------------- /WKWebViewTest/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WKWebViewTest 4 | // 5 | // Created by Felix Deimel on 10.06.15. 6 | // Copyright © 2015 Lemon Mojo - Felix Deimel e.U. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import 11 | #import "WKWebView+Screenshot.h" 12 | 13 | @interface AppDelegate () 14 | 15 | @property (assign) IBOutlet NSWindow *window; 16 | @property (assign) IBOutlet NSTabView *tabView; 17 | @property (assign) IBOutlet NSImageView *imageView; 18 | 19 | @end 20 | 21 | @implementation AppDelegate { 22 | NSMutableArray *m_webViews; 23 | } 24 | 25 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification 26 | { 27 | m_webViews = [[NSMutableArray alloc] init]; 28 | [self.imageView registeredDraggedTypes]; 29 | WKWebViewConfiguration* config = [[[WKWebViewConfiguration alloc] init] autorelease]; 30 | WKPreferences* prefs = config.preferences; 31 | 32 | prefs.javaScriptEnabled = YES; 33 | prefs.javaEnabled = YES; 34 | prefs.javaScriptCanOpenWindowsAutomatically = YES; 35 | prefs.plugInsEnabled = YES; 36 | 37 | [m_webViews addObject:[self addWebViewWithConfig:config url:@"http://www.google.com/" toView:[self.tabView.tabViewItems[0] view]]]; 38 | [m_webViews addObject:[self addWebViewWithConfig:config url:@"http://www.javatester.org/" toView:[self.tabView.tabViewItems[1] view]]]; 39 | [m_webViews addObject:[self addWebViewWithConfig:config url:@"http://www.audiotool.com/app" toView:[self.tabView.tabViewItems[2] view]]]; 40 | [m_webViews addObject:[self addWebViewWithConfig:config url:@"http://www.medicalrounds.com/quicktimecheck/troubleshooting.html" toView:[self.tabView.tabViewItems[3] view]]]; 41 | } 42 | 43 | - (WKWebView*)addWebViewWithConfig:(WKWebViewConfiguration*)config url:(NSString*)url toView:(NSView*)view 44 | { 45 | WKWebView* v = [[[WKWebView alloc] initWithFrame:view.bounds configuration:config] autorelease]; 46 | v.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; 47 | 48 | [view addSubview:v]; 49 | 50 | NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:url]]; 51 | [v loadRequest:req]; 52 | 53 | return v; 54 | } 55 | 56 | - (IBAction)buttonCaptureScreenshot_action:(id)sender 57 | { 58 | WKWebView* wkWebView = [m_webViews objectAtIndex:[self.tabView indexOfTabViewItem:self.tabView.selectedTabViewItem]]; 59 | 60 | [self captureScreenshotAsyncInWKWebView:wkWebView]; 61 | } 62 | 63 | - (void)captureScreenshotAsyncInWKWebView:(WKWebView*)wkWebView 64 | { 65 | [wkWebView captureScreenshotWithCompletionHandler:^(NSImage *screenshot) { 66 | self.imageView.image = screenshot; 67 | }]; 68 | } 69 | 70 | - (void)captureScreenshotSyncInWKWebView:(WKWebView*)wkWebView 71 | { 72 | dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)); 73 | self.imageView.image = [wkWebView captureScreenshotWithTimeout:timeout]; 74 | } 75 | 76 | @end -------------------------------------------------------------------------------- /WKWebViewTest/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /WKWebViewTest/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 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 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | Default 541 | 542 | 543 | 544 | 545 | 546 | 547 | Left to Right 548 | 549 | 550 | 551 | 552 | 553 | 554 | Right to Left 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | Default 566 | 567 | 568 | 569 | 570 | 571 | 572 | Left to Right 573 | 574 | 575 | 576 | 577 | 578 | 579 | Right to Left 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | -------------------------------------------------------------------------------- /WKWebViewTest/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015 Lemon Mojo - Felix Deimel e.U. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | NSAppTransportSecurity 34 | 35 | NSAllowsArbitraryLoads 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /WKWebViewTest/WKWebView+Screenshot.h: -------------------------------------------------------------------------------- 1 | // 2 | // LMThumbnailView.h 3 | // WKWebViewTest 4 | // 5 | // Created by Felix Deimel on 21.08.15. 6 | // Copyright (c) 2015 Lemon Mojo - Felix Deimel e.U. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LMFakeWKView : NSObject 12 | 13 | - (instancetype)initWithWebView:(WKWebView*)webView; 14 | 15 | @property (strong) WKWebView* webView; 16 | 17 | @end 18 | 19 | #if WK_API_ENABLED 20 | #if !TARGET_OS_IPHONE 21 | @class WKView; 22 | 23 | NS_CLASS_AVAILABLE(10_10, 8_0) /* WK_CLASS_AVAILABLE(10_10, 8_0) */ 24 | @interface _WKThumbnailView : NSView 25 | 26 | - (instancetype)initWithFrame:(NSRect)frame fromWKView:(WKView *)wkView; 27 | 28 | @property (nonatomic) CGFloat scale; 29 | @property (nonatomic, readonly) CGSize snapshotSize; 30 | @property (nonatomic) CGSize maximumSnapshotSize; 31 | @property (nonatomic) BOOL exclusivelyUsesSnapshot; 32 | 33 | // Defaults to NO. 34 | @property (nonatomic) BOOL shouldKeepSnapshotWhenRemovedFromSuperview; 35 | 36 | // This should be removed when all clients go away; it is always YES now. 37 | @property (nonatomic) BOOL usesSnapshot; 38 | 39 | - (void)requestSnapshot; 40 | 41 | - (void)_didTakeSnapshot:(CGImageRef)image; 42 | - (void)_viewWasParented; 43 | - (void)_viewWasUnparented; 44 | 45 | @end 46 | #endif // TARGET_OS_IPHONE 47 | #endif // WK_API_ENABLED 48 | 49 | typedef void (^CaptureScreenshotCompletionHandler) (NSImage* screenshot); 50 | 51 | NS_CLASS_AVAILABLE(10_10, 8_0) 52 | @interface LMWKThumbnailView : _WKThumbnailView 53 | 54 | @property (strong) LMFakeWKView* fakeWKView; 55 | 56 | + (void)captureScreenshotOfWKWebView:(WKWebView*)wkWebView withCompletionHandler:(CaptureScreenshotCompletionHandler)completionHandler; 57 | 58 | - (instancetype)initWithWKWebView:(WKWebView*)wkWebView completionHandler:(CaptureScreenshotCompletionHandler)completionHandler; 59 | - (void)captureScreenshot; 60 | 61 | @end 62 | 63 | @interface WKWebView (Screenshot) 64 | 65 | - (void)captureScreenshotWithCompletionHandler:(CaptureScreenshotCompletionHandler)completionHandler; 66 | - (NSImage*)captureScreenshotWithTimeout:(dispatch_time_t)timeout; 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /WKWebViewTest/WKWebView+Screenshot.m: -------------------------------------------------------------------------------- 1 | // 2 | // LMThumbnailView.m 3 | // WKWebViewTest 4 | // 5 | // Created by Felix Deimel on 21.08.15. 6 | // Copyright (c) 2015 Lemon Mojo - Felix Deimel e.U. All rights reserved. 7 | // 8 | 9 | #import "WKWebView+Screenshot.h" 10 | 11 | @implementation LMFakeWKView 12 | 13 | - (instancetype)initWithWebView:(WKWebView*)webView 14 | { 15 | self = [super init]; 16 | 17 | if (self) { 18 | self.webView = webView; 19 | } 20 | 21 | return self; 22 | } 23 | 24 | + (instancetype)fakeWKViewWithWebView:(WKWebView*)webView 25 | { 26 | return [[[LMFakeWKView alloc] initWithWebView:webView] autorelease]; 27 | } 28 | 29 | - (void)dealloc 30 | { 31 | self.webView = nil; 32 | 33 | [super dealloc]; 34 | } 35 | 36 | - (NSView*)_thumbnailView 37 | { 38 | return nil; 39 | } 40 | 41 | - (NSWindow*)window 42 | { 43 | return self.webView.window; 44 | } 45 | 46 | - (void*)pageRef 47 | { 48 | return [self.webView performSelector:@selector(_pageForTesting)]; 49 | } 50 | 51 | @end 52 | 53 | @implementation LMWKThumbnailView { 54 | CaptureScreenshotCompletionHandler _completionHandler; 55 | } 56 | 57 | + (void)captureScreenshotOfWKWebView:(WKWebView*)wkWebView withCompletionHandler:(CaptureScreenshotCompletionHandler)completionHandler 58 | { 59 | __block LMWKThumbnailView* thumbnailView = [[LMWKThumbnailView alloc] initWithWKWebView:wkWebView completionHandler:^(NSImage *screenshot) { 60 | [thumbnailView release]; 61 | 62 | if (completionHandler) { 63 | completionHandler(screenshot); 64 | } 65 | }]; 66 | 67 | [thumbnailView captureScreenshot]; 68 | } 69 | 70 | - (instancetype)initWithWKWebView:(WKWebView*)wkWebView completionHandler:(CaptureScreenshotCompletionHandler)completionHandler 71 | { 72 | self.fakeWKView = [LMFakeWKView fakeWKViewWithWebView:wkWebView]; 73 | 74 | if (self = [super initWithFrame:NSZeroRect fromWKView:(WKView*)self.fakeWKView]) { 75 | self.exclusivelyUsesSnapshot = YES; 76 | _completionHandler = [completionHandler copy]; 77 | } 78 | 79 | return self; 80 | } 81 | 82 | - (void)dealloc 83 | { 84 | [_completionHandler release]; _completionHandler = nil; 85 | self.fakeWKView = nil; 86 | 87 | [super dealloc]; 88 | } 89 | 90 | - (void)captureScreenshot 91 | { 92 | [self requestSnapshot]; 93 | } 94 | 95 | - (void)_didTakeSnapshot:(CGImageRef)image 96 | { 97 | NSImage *screenshot = nil; 98 | 99 | if (image) { 100 | screenshot = [[[NSImage alloc] initWithCGImage:image size:NSZeroSize] autorelease]; 101 | } 102 | 103 | CaptureScreenshotCompletionHandler completionHandler = _completionHandler; 104 | 105 | if (completionHandler) { 106 | completionHandler(screenshot); 107 | } 108 | } 109 | 110 | @end 111 | 112 | @implementation WKWebView (Screenshot) 113 | 114 | - (void)captureScreenshotWithCompletionHandler:(CaptureScreenshotCompletionHandler)completionHandler 115 | { 116 | [LMWKThumbnailView captureScreenshotOfWKWebView:self withCompletionHandler:completionHandler]; 117 | } 118 | 119 | - (NSImage*)captureScreenshotWithTimeout:(dispatch_time_t)timeout 120 | { 121 | dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 122 | 123 | __block NSImage* theScreenshot = nil; 124 | 125 | [self captureScreenshotWithCompletionHandler:^(NSImage *screenshot) { 126 | if (screenshot) { 127 | theScreenshot = [screenshot retain]; 128 | } 129 | 130 | dispatch_semaphore_signal(semaphore); 131 | }]; 132 | 133 | while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW)) { 134 | if (dispatch_time(DISPATCH_TIME_NOW, 0) > timeout) { 135 | theScreenshot = nil; 136 | break; 137 | } 138 | 139 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0]]; 140 | } 141 | 142 | return [theScreenshot autorelease]; 143 | } 144 | 145 | @end 146 | -------------------------------------------------------------------------------- /WKWebViewTest/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WKWebViewTest 4 | // 5 | // Created by Felix Deimel on 10.06.15. 6 | // Copyright © 2015 Lemon Mojo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | --------------------------------------------------------------------------------