包含适用于iOS8的WebKit框架无法验证

wei*_*yin 11 xcode webkit ios ios8 wkwebview

我正在使用WebKit框架的WKWebView,在尝试提交到应用程序商店时,我收到此错误:

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
Run Code Online (Sandbox Code Playgroud)

如果我将部署目标设置为8.0,那么错误就会消失,但我也想支持iOS 7.该错误似乎是iOS7也有WebKit框架的结果,但它当时是私有的.

因此,我想动态链接到WebKit库.我怎么能在XCode中做到这一点?

wei*_*yin 16

好吧,经过几个小时的挫折,终于让这个工作了.

在Apple修复验证之前,关键是在运行时动态链接到WebKit框架.您的项目应该已经使用运行时检查优雅地回退到iOS7及更早版本的UIWebView,即检查[WKWebView类].

步骤1:从项目设置中删除WebKit框架.转到目标 - >常规 - >链接的框架和库,然后删除WebKit.此时,您的代码将编译但无法链接,因为它无法解析WKWebView和关联的符号.

第2步:编辑main.m文件以动态加载库:

#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]));
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用运行时操作系统版本检查,因为Apple只允许从iOS 8开始动态库加载.模拟器与实际设备的库位置不同,所以我使用条件编译来检查它.

第3步:由于库是动态加载的,调用[WKWebView类]和[WKWebView alloc]将不起作用.浏览您的代码,更改每个实例

[WKWebView class]
// change to:
NSClassFromString(@"WKWebView")
Run Code Online (Sandbox Code Playgroud)

每次分配WKWebView时都要更改:

[WKWebView alloc]
// change to:
[NSClassFromString(@"WKWebView") alloc]
Run Code Online (Sandbox Code Playgroud)

您还必须为关联的类执行此操作,包括WKWebViewConfiguration,WKProcessPool,WKUserScript以及您正在使用的其他任何类.检查链接器错误,查找可能遗漏的任何内容.

第4步:现在您的代码应该成功编译.打包,提交到应用商店,并庆祝.