Andrew Ebling
Andrew Ebling

Reputation: 10283

Variable (enum?) holding one of two types in Swift 2

In a UIViewController subclass need to declare a variable called webView which can be of type UIWebView or WKWebView (depending on iOS version).

Is there a better way to do this (perhaps using an enum?) than one of these options:

  1. Declaring the variable of type UIView and then conditionally casting to the two types every time I need to access it
  2. Not declaring the variable in the common parent UIViewController super class, but declaring the variable of the specific type twice over in the two specific UIViewController subclasses? Feels like it violates the "Don't Repeat Yourself"/DRY principle.

Upvotes: 3

Views: 159

Answers (2)

Martin R
Martin R

Reputation: 539745

You could define a protocol containing the common methods that you want to call on the view:

protocol MyWebView {
    // ...
}

Then make both UIWebView and WKWebView conform to that protocol (via extensions):

extension UIWebView : MyWebView {

}

@available(iOS 8.0, *)
extension WKWebView : MyWebView {

}

Now you can declare the instance variable as

var webView : MyWebView!

and initialize it depending on the iOS version:

if #available(iOS 8, *){
    webView = WKWebView()
} else {
    webView = UIWebView()
}

Upvotes: 3

erdekhayser
erdekhayser

Reputation: 6657

I had a similar problem in an app of mine, using a different deprecated framework. This solution worked for me:

Create a property as shown below:

var webView: AnyObject!

In viewDidLoad, initialize the web view using this code:

if #available(iOS 9, *){
    webView = WKWebView()
} else {
    webView = UIWebView()
}

Elsewhere in your code, when you need to do something with this web view, you need to do something similar:

if #available(iOS 9, *){
    let newWebView = webView as! WKWebView
    // use newWebView
} else {
    let oldWebView = webView as! UIWebView
    // use oldWebView
}

Note: Martin R's suggestion to use a type alias may work as well, but this solution I have tested myself.

Upvotes: 0

Related Questions