Xcode 6 + iOS 8 SDK但是部署在iOS 7上(UIWebKit和WKWebKit)

18
我们正在使用Xcode 6 beta 5 + Swift和iOS 8 SDK创建一个应用程序。我们希望也能部署到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这样做了)请参阅屏幕截图:

enter image description here

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


这些是链接器错误,而不是编译器错误。你是从Xcode 6还是Xcode 5中得到这些错误的?顺便说一下 - 不要检查iOS版本以确定要做什么。相反,检查给定的类或方法是否存在。 - rmaddy
2个回答

18

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

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

Objective-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)
}

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

Objective-C:

if(wkWebView) {
    // WKWebView specific code
}
else {
    // UIWebView specific code
}

Swift:

if let w=wkWebView {
    // WKWebView specific code
}
else if let w=uiWebView {
    // UIWebView specific code
}

1
这些都没有解决关于链接器错误的问题。 - rmaddy
谢谢kkoltzau,让我试一下并回报。有趣的是你可以通过“NSClassFromString”设置类。 - netwire
@rmaddy提到的对WebKit.framework进行弱链接,涉及到第二句话中提到的链接器错误。 - kevin
感谢kkoltzau将WebKit.framework设置为可选项。我无法粘贴截图,但我会将其作为答案提供给其他人。 - netwire
@Dean 关于 WKNavigationDelegate,只需像往常一样实现它即可。我不知道为什么 WKWebView 会创建失败,假设已正确链接 WebKit.framework。 - kevin
显示剩余3条评论

2

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


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接