0

I have a delete button on a cell and it was crashing my app in iOS7 but not in iOS8. I later found out the crash was caused by by how deep down I was digging into my view hierarchy.

To make things clearer here is the code that solved the issue:

func didTapDeleteButton(sender: UIButton) {
        var cell: HoursOfOperationTableViewCell!
        if let gotModernAlert: AnyClass = NSClassFromString("UIAlertController") {
            println("UIAlertController can be instantiated")
            //make and use a UIAlertController
            cell = sender.superview?.superview? as HoursOfOperationTableViewCell
        }
        else {       
            println("UIAlertController can NOT be instantiated")
            cell = sender.superview?.superview?.superview? as HoursOfOperationTableViewCell
        }

As you can see I have to go further down into my view hierarchy to get to my custom cell view in iOS 7.

I was wondering if there was a more efficient way of checking the iOS version?

If I don't check then my app crashes in iOS7 if I leave the code like this:

cell = sender.superview?.superview? as HoursOfOperationTableViewCell

Thanks for your time.

LondonGuy
  • 10,778
  • 11
  • 79
  • 151
  • You're doing it right. It's better to check for existence of the class, than for the OS version. Maybe the class name will change, maybe it will be deprecated/removed in iOS 12, etc. – Craig Otis Oct 13 '14 at 13:45
  • I take it none of the solutions are suitable? Could you clarify why? – Daniel Galasko Oct 15 '14 at 04:58
  • @DanielGalasko I've put this part of my project on hold but will get back to it soon and try out these solutions. – LondonGuy Oct 15 '14 at 18:19

3 Answers3

1

To test if a class is loaded in the current runtime, you could call the following:

var classExistsAndIsSafeToUse = countElements(NSStringFromClass(object_getClass(UIAlertController))) > 0

You should always check for the existence of a particular class over checking the iOS version.

That being said, for checking the iOS version, below is an excerpt from my solution on just that

New in iOS 8 is NSProcessInfo that integrates greatly with Swift and allows for better semantic versioning checks. Thanks to NSHipster we can see a clean and canonical source from where the OS version can be derived.

For minimum deployment targets of iOS 8.0 or above, use NSProcessInfo operatingSystemVersion or isOperatingSystemAtLeastVersion.

This would yield the following:

let minimumVersion = NSOperatingSystemVersion(majorVersion: 3, minorVersion: 1, patchVersion: 3)
if NSProcessInfo().isOperatingSystemAtLeastVersion(minimumVersion) {
    //do some fun stuff
}

For minimum deployment targets of iOS 7.1 or below, use compare with NSStringCompareOptions.NumericSearch on UIDevice systemVersion.

This would yield:

let minimumVersionString = "3.1.3"
let versionComparison: NSComparisonResult = UIDevice.currentDevice().systemVersion.compare(minimumVersionString,

options: NSStringCompareOptions.NumericSearch) if versionComparison == .OrderedDescending { //do some fun stuff }

EDIT

as a side note, if you see something like this:

cell = sender.superview?.superview? as HoursOfOperationTableViewCell

your code has begun to exhibit whats known as code smell, you should consider implementing your view logic inside of your view, the controllers should not have a deep knowledge into the view hierarchy. Remember, the goal is on writing easy to change code. Consider implementing abstraction, delegation and singular responsibility principled design.

Good luck

Community
  • 1
  • 1
Daniel Galasko
  • 23,617
  • 8
  • 77
  • 97
0

You can simply check [[UIDevice currentDevice] systemVersion]. This returns an NSString so you will need to convert to a float if you want to compare.

Jason Grandelli
  • 342
  • 3
  • 10
0

Another way is using NSFoundationVersionNumber. Declare the following constants in a file where you keep global constants.

let iOS7 = floor(NSFoundationVersionNumber) <= floor(NSFoundationVersionNumber_iOS_7_1)
let iOS8 = floor(NSFoundationVersionNumber) > floor(NSFoundationVersionNumber_iOS_7_1)

And check for the version like this.

if iOS8 {
    // Use iOS 8 APIs
} else {
    // Fallback for older iOS versions
}
Isuru
  • 30,617
  • 60
  • 187
  • 303