We are creating an app using Xcode 6 beta 5 + Swift on iOS 8 SDK. We'd like to deploy to iOS 7 as well. Is that possible? When we set the deployment target of the project to 7.0, we get compile time errors like this:
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)
I believe that's because we are using WKWebKit
, which is supported by iOS 8+ only. We are ok with using UIWebKit
for iOS 7 but WKWebKit
for iOS 8. How do we define that?
Our class definition looks like this...
import WebKit
class WebViewController: UIViewController, WKNavigationDelegate {
...
}
and it's called by:
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let destinationVC = mainStoryboard.instantiateViewControllerWithIdentifier("WebViewController") as WebViewController
presentViewController(destinationVC, animated: true, completion: nil)
I was thinking about using this fragment to call presentViewController
but that doesn't solve the compile time issues. (NSFoundationVersionNumber
doesn't solve compile time issues either)
if ((UIDevice.currentDevice().systemVersion as NSString).floatValue >= 8.0) {
} else {
}
UPDATE: kkoltzau has the correct answer. I'm adding some more info for others.
First, go to your Project
, click on General
, scroll down to Linked Frameworks and Libraries
, and add WebKit.framework
as Optional. (I also did it for UIKit.framework
) See screenshot:
As for my WebViewController
class. It still imports UIKit
and WebKit
. but the viewDidLoad()
sets the view based on kkoltzau's example. Then whenever I need to load/reload the web page, it checks for existence of wkWebView
.
You will need to check if WKWebView is available, and fall back to UIWebView if its not.
Make sure you weak link WebKit.framework (set to optional)
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];
}
Swift:
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)
}
Then elsewhere in your code:
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
}
If you need to support iOS7, you cannot use WebKit2 (WK*
) classes, or you need to implement twice the logic, once for iOS8 using WK*
and once using UIWeb*
, and at runtime choose according to the operating system version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With