Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do an availability check on class variables

Tags:

ios

swift

My current project supports iOS 7+ and in one of my view controllers I'm trying to use both UIAlertView and UIAlertController.

I have the #available conditional working in my methods, but I'm not sure how to wrap the vars.

When I have:

var alertController: UIAlertController!
var alertView: UIAlertView!

I get an error message telling me UIAlertController is only available in iOS 8+ and the option to 'Fix It' by "Adding @available to enclosing class". However I think this marks the entire class, and that's not what I want.

like image 497
Beau Nouvelle Avatar asked Jul 09 '15 22:07

Beau Nouvelle


People also ask

How do you access class variables?

Accessing Class Variables We can access static variables either by class name or by object reference, but it is recommended to use the class name. Access inside the constructor by using either self parameter or class name. Access from outside of class by using either object reference or class name.

Where class variables are stored in Python?

Defined outside of all the methods, class variables are, by convention, typically placed right below the class header and before the constructor method and other methods.

How do you print a class variable in Python?

How to Print the Type of a Variable in Python. To get the type of a variable in Python, you can use the built-in type() function. In Python, everything is an object. So, when you use the type() function to print the type of the value stored in a variable to the console, it returns the class type of the object.

How do you assign a class to a variable in Python?

Use dot notation or setattr() function to set the value of a class attribute. Python is a dynamic language. Therefore, you can assign a class variable to a class at runtime. Python stores class variables in the __dict__ attribute.


2 Answers

I just came across this issue and I too have struggled to find a solution so ended up making the variable lazy and defaulting to nil whilst adding availability annotations

For your implementation that would look as follows:

@available(iOS 8.0, *)
lazy var alertController: UIAlertController? = { return nil }()

Then whenever you try and access that property the compiler will make sure its guarded in an availability check so that you always have:

if #available(iOS 8.0, *) {
    self.alertController = ...
} else 
    self.alertView = ...
}
like image 103
Daniel Galasko Avatar answered Oct 04 '22 04:10

Daniel Galasko


If you just need to use alert in one function, you can just move your code into the func block and XCode 7 will come up with suggestion that works.

What if you need to use alert in several func blocks and refer to the same alert object over and over?

You can use a new UIResponder and downcast it to either UIAlertController or UIView based on availability. I haven't test it in my project, but it should work.

let alertContainer: UIResponder?

init () {
    if #available(iOS 8.0, *) {
        let alertController: UIAlertController!
        alertContainer = alertController
    } else {
        let alertView: UIAlertView!
        alertContainer = alertView
    }
}

func someFunction () {
    if #available(iOS 8.0, *) {
        var alertController = alertContainer as! UIAlertController
        // use the alertController
    } else {
        var alertView = alertContainer as! UIAlertView
        // use the UIAlertView
    }
}

This actually adds more codes, but it passes Xcode's check. If you come up with a better solution, please let me know.

like image 36
Oliver Zhang Avatar answered Oct 04 '22 05:10

Oliver Zhang