Enabling WebKit framework for iOS8 does not allow validation

I use the WebKit framework WKWebView and when I try to send to the application store, I get this error:

Your app contains non-public API usage. Please review the errors, correct them, and resubmit your application. The app links to non-public libraries in Payload...: /System/Library/PrivateFrameworks/WebKit.framework/WebKit 

If I set the deployment target to 8.0, the error will disappear, but I would also like to support iOS 7. The error seems to be the result of the fact that iOS7 also has a WebKit structure, but then it was closed.

I would therefore like to dynamically reference the WebKit library. How to do it in Xcode?

+11
ios xcode ios8 webkit wkwebview
Sep 17 '14 at 17:48
source share
1 answer

Well, finally, it happened after many hours of disappointment.

Until Apple fixes the validation, the key must dynamically bind to the WebKit framework at run time. Your project should already use runtime checks to gracefully revert to UIWebView for iOS7 and earlier, i.e. To check for [class WKWebView].

Step 1: Remove the WebKit structure from the project settings. Go to your goal -> General -> Related Structures and Libraries and uninstall WebKit. At this point, your code will compile, but will not be linked, because it cannot resolve WKWebView and its associated characters.

Step 2: Edit the main.m file to dynamically load the library:

 #import <UIKit/UIKit.h> #import <TargetConditionals.h> #import <dlfcn.h> #import "MyAppDelegate.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([MyAppDelegate class])); } } 

I use version verification of the operating system because Apple allows the loading of a dynamic library starting with iOS 8. The location of the library is different from the simulator and the actual devices, so I use conditional compilation to verify this.

Step 3:. Since the library loads dynamically, calling [WKWebView class] and [WKWebView alloc] will not work. Go through your code by changing each instance

 [WKWebView class] // change to: NSClassFromString(@"WKWebView") 

And change every time you select WKWebView:

 [WKWebView alloc] // change to: [NSClassFromString(@"WKWebView") alloc] 

You should also do this for related classes, including WKWebViewConfiguration, WKProcessPool, WKUserScript and everything you use. Check linker errors for anything you might have missed.

Step 4: Your code should now compile successfully. Package, send to the app store and celebrate.

+16
Sep 19 '14 at 1:43
source share



All Articles