Xcode 6 + iOS 8 SDK 但部署在 iOS 7 (UIWebKit & WKWebKit)

Posted

技术标签:

【中文标题】Xcode 6 + iOS 8 SDK 但部署在 iOS 7 (UIWebKit & WKWebKit)【英文标题】:Xcode 6 + iOS 8 SDK but deploy on iOS 7 (UIWebKit & WKWebKit) 【发布时间】:2014-08-16 14:42:22 【问题描述】:

我们正在 ios 8 SDK 上使用 Xcode 6 beta 5 + Swift 创建一个应用程序。我们也想部署到 iOS 7。那可能吗?当我们将项目的部署目标设置为 7.0 时,我们会得到如下编译时错误:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_WKPreferences", referenced from:
      __TMaCSo13WKPreferences in WebViewController.o
  "_OBJC_CLASS_$_WKWebView", referenced from:
      __TMaCSo9WKWebView in WebViewController.o
  "_OBJC_CLASS_$_WKWebViewConfiguration", referenced from:
      __TMaCSo22WKWebViewConfiguration in WebViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我相信这是因为我们使用的是WKWebKit,它仅受 iOS 8+ 支持。我们可以在 iOS 7 上使用 UIWebKit,但在 iOS 8 上使用 WKWebKit。我们如何定义它?

我们的类定义如下所示...

import WebKit

class WebViewController: UIViewController, WKNavigationDelegate 
   ...

它的调用者是:

        let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let destinationVC = mainStoryboard.instantiateViewControllerWithIdentifier("WebViewController") as WebViewController
        presentViewController(destinationVC, animated: true, completion: nil)

我正在考虑使用这个片段来调用presentViewController,但这并不能解决编译时间问题。 (NSFoundationVersionNumber 也不能解决编译时问题)

    if ((UIDevice.currentDevice().systemVersion as NSString).floatValue >= 8.0) 

     else 

    

更新:kkoltzau 有正确的答案。我正在为其他人添加更多信息。

首先,转到您的Project,单击General,向下滚动到Linked Frameworks and Libraries,然后将WebKit.framework 添加为可选。 (我也是为UIKit.framework做的)看截图:

至于我的WebViewController 班级。它仍然导入UIKitWebKit。但是viewDidLoad() 根据kkoltzau 的示例设置视图。然后,每当我需要加载/重新加载网页时,它都会检查 wkWebView 是否存在。

【问题讨论】:

这些是链接器错误,而不是编译器错误。您是从 Xcode 6 还是 Xcode 5 获得的?顺便说一句 - 不要检查 iOS 版本来确定要做什么。相反,检查给定的类或方法是否存在。 Xcode build failure "Undefined symbols for architecture x86_64" 的可能重复项 【参考方案1】:

您需要检查 WKWebView 是否可用,如果不可用则回退到 UIWebView。

确保你弱链接 WebKit.framework(设置为可选)

目标-C:

WKWebView *wkWebView = nil;
UIWebView *uiWebView = nil;

Class wkWebViewClass = NSClassFromString(@"WKWebView");
if(wkWebViewClass) 
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    // ...
    wkWebView = [[wkWebViewClass alloc] initWithFrame:frame configuration:config];
    [self.view addSubview:wkWebView];

else 
    uiWebView = [[UIWebView alloc] initWithFrame:frame];
    [self.view addSubview:uiWebView];

斯威夫特:

var wkWebView : WKWebView?
var uiWebView : UIWebView?

if NSClassFromString("WKWebView") 
    let config = WKWebViewConfiguration()
    // ...
    wkWebView = WKWebView(frame: frame, configuration: config)
    self.view.addSubview(wkWebView)

else 
    uiWebView = UIWebView(frame: frame)
    self.view.addSubview(uiWebView)

然后在您的代码中的其他地方:

目标-C:

if(wkWebView) 
    // WKWebView specific code

else 
    // UIWebView specific code

斯威夫特:

if let w=wkWebView 
    // WKWebView specific code

else if let w=uiWebView 
    // UIWebView specific code

【讨论】:

这些都没有解决有关链接器错误的问题。 感谢 kkoltzau,让我尝试并报告。有趣的是,您可以通过 'NSClassFromString' 设置课程 @rmaddy 第二句中提到的对 WebKit.framework 的弱链接涵盖了链接器错误。 感谢 kkoltzau 将 WebKit.framework 设置为可选。我无法粘贴屏幕截图,但我会这样做作为其他人的答案。 我的类也实现了WKNavigationDelegate,包括`func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation)`和func webView(webView: WKWebView, didCommitNavigation navigation: WKNavigation)等方法。我如何将它们包含在此示例中?【参考方案2】:

如果需要支持iOS7,则不能使用WebKit2(WK*)类,或者需要实现两次逻辑,iOS8一次使用WK*,一次使用UIWeb*,运行时根据选择操作系统版本。

【讨论】:

关于“确保弱链接 WebKit.framework(设置为可选)”的句子 2 非常重要。实际上我什至没有列出 WebKit.Framework,所以我需要添加它并设置为 Optional。

以上是关于Xcode 6 + iOS 8 SDK 但部署在 iOS 7 (UIWebKit & WKWebKit)的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 8 Beta 6 不支持 iOS 10 Beta 7 sdk

iCloud Core Data 在 Xcode 6 / ios 8 SDK 中运行后不可用

无法在 Xcode 3.2.6 上为 iOS 构建 Facebook SDK

尽管 Xcode 是最新的,但无法将 iOS 应用程序部署到 App Store

适用于 iOS 7 应用程序的 XCode 6 中的 UISplitViewController

使用 iOS 6 SDK 和 Xcode 4.5 构建 armv6 架构(目标 iOS 3.1.3)?