包含 iOS8 的 WebKit 框架验证失败

Posted

技术标签:

【中文标题】包含 iOS8 的 WebKit 框架验证失败【英文标题】:Including WebKit framework for iOS8 fails validation 【发布时间】:2014-09-17 17:48:41 【问题描述】:

我正在使用 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

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

因此,我想动态链接到 WebKit 库。我如何在 XCode 中做到这一点?

【问题讨论】:

当您的用户使用 iOS 7 时,您将需要使用 UIWebView(不清楚您是否正在尝试)。这应该工作:***.com/q/25341238/1580288 我对 ios7 进行运行时检查并使用 UIWebView。它在我的开发设备上运行良好。我遇到的问题是试图通过验证。谢谢! 我也有同样的问题。我只在 iOS 8 上使用 WebKit,但我的应用部署到 iOS 7 【参考方案1】:

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

在 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]));
    

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

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

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

并且每次分配 WKWebView 时都会改变:

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

您还必须对关联的类执行此操作,包括 WKWebViewConfiguration, WKProcessPool、WKUserScript 以及您正在使用的任何其他工具。检查您的链接器错误是否有您可能遗漏的任何内容。

第 4 步:现在您的代码应该可以成功编译。打包,提交到应用商店,然后庆祝。

【讨论】:

对于第 2 步,另一种方法是将库添加为可选,而不是在需要支持 iOS7 时添加。 当我将 WebKit.framework 添加为可选时,验证错误又回来了。但事实证明,如果您已将所有内容移至 NSClassFromString ,则根本不需要告诉链接器有关这些类的信息!我正在更新以删除不必要的步骤。 我遇到了同样的问题。谢谢你的方法。 @weiyin 由于库是动态加载的,因此使用 WKWebView 和关联的类并不那么方便。我编写了一个调用类来执行带有任何类型参数的选择器。希望帮助别人。 [链接][1] [1]:github.com/jnuhwb/WBInvocation @WellbinHuang 您仍然可以导入 WebKit 标头并正常使用它们的选择器。可以用 WebKit 编译,只是不要链接它。 拯救我的生命!谢谢。

以上是关于包含 iOS8 的 WebKit 框架验证失败的主要内容,如果未能解决你的问题,请参考以下文章

Struts2验证框架_xml验证失败

iOS8 WebKit库之——WKWebView篇

iOS:WebKit内核框架的应用与解析

实体框架中一个或多个实体的可空布尔属性验证失败

iOS8 In App Purchase收据验证

Zend 框架 - 定制表单验证