Xcode 6 + iOS 8 SDK but deploy on iOS 7 (UIWebKit & WKWebKit)


Answers

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.

Question

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.







UPD

Apple requires to use arm64 architecture. Do not use x32 libraries in your project

So the answer below is not correct anymore!


Old answer

The new Xcode 5.1 sets the architecture armv7,armv7s,and arm64 as default.

And sometimes the error "build failure “Undefined symbols for architecture x86_64”" may be caused by this. Because, some libs (not Apple's) were compiled for x32 originally and doesn't support x64.

So what you need, is to change the "Architectures" for your project target like this

NB. If you're using Cocoapods - you should do the same for "Pods" target.




Tags