Check availability in switch statement
Asked Answered
P

3

20

if a Enum type add new case in new os version,how to check availability in switch statement? Like a Enum in StoreKit below

public enum Code : Int {
    public typealias _ErrorType = SKError
    case unknown
    case clientInvalid 
    case paymentCancelled 
    case paymentInvalid 
    case paymentNotAllowed
    case storeProductNotAvailable
    @available(iOS 9.3, *)
    case cloudServicePermissionDenied 
    @available(iOS 9.3, *)
    case cloudServiceNetworkConnectionFailed
    @available(iOS 10.3, *)
    case cloudServiceRevoked
}

Is below code the only solution? It's too redundant.

if #available(iOS 10.3, *) {
    switch code {
        //all cases available in 10.3
        ...
    }
} else if #available(iOS 9.3, *) {
    switch code {
       //all cases available in 9.3
       ...
    }
} else {
    switch code {
        //all cases available below 9.3
        ...
    }
}

-----------------new-------------------------

I think It's not a question. All cases writed in one switch is fine, if statement is unneccessary. Because new added cases would not called in low iOS version.

Petulia answered 2/6, 2017 at 9:39 Comment(0)
F
6

Usually it happens on a new versions of Xcode with fresh SDK and toolchain. So, for example Xcode 12 is bundled with iOS 14 SDK and Swift 5.3 and has a similar issues with new cases like PHAuthorizationStatus.limited which marked as available only in iOS 14 and it will break switch statement without default case.

As a workaround to make both version of Xcode 11 and Xcode 12 working I'd like to suggest following solution with checking Swift version:

    switch PHPhotoLibrary.authorizationStatus() {
    case .authorized:
        presentImagePicker()
    case .denied:
        presentAccessDeniedAlert()
    case .notDetermined:
        requestAuthorization()
    case .restricted:
        break
#if swift(>=5.3) // Xcode 12 iOS 14 support
    case .limited:
        presentImagePicker()
#endif
    @unknown default:
        assertionFailure()
    }
Fallacious answered 24/6, 2020 at 9:14 Comment(1)
Had this exact problem with the addition of .Mac to the UIUserInterfaceIdiom enum. Used this to make it compile for Xcode11 (since the majority of the team is still on it) and Xcode12 so that we can test iOS14 features.Paterfamilias
P
3

I suppose you could do like this:

switch transactionCode {
    case SKError.unknown:
        //Handle case
    //(rest of ios < 9.3 available types)
    default:
        if #available(iOS 9.3, *) {
            if transactionCode == SKError.cloudServiceNetworkConnectionFailed {
                //Handle case
            }
            else if transactionCode == SKError.cloudServicePermissionDenied {
                //Handle case
            }
        }
        if #available(iOS 10.3, *) {
            if transactionCode == SKError.cloudServiceRevoked {
                //Handle case
            }
        }
    }

You are unable to make an exhaustive switch statement without the default case, but theres no redundant code.

Postremogeniture answered 29/9, 2017 at 21:16 Comment(0)
L
-1

How about this?

if error.code == SKError.unknown {

} else if error.code == SKError.clientInvalid {

} else if error.code == SKError.paymentCancelled {

} else if error.code == SKError.paymentInvalid {

} else if error.code == SKError.paymentNotAllowed {

} else if error.code == SKError.storeProductNotAvailable {

} else if #available(iOS 9.3, *), error.code == SKError.cloudServicePermissionDenied {

} else if #available(iOS 9.3, *), error.code == SKError.cloudServiceNetworkConnectionFailed {

} else if #available(iOS 10.3, *), error.code == SKError.cloudServiceRevoked {

}
Lichfield answered 22/1, 2018 at 2:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.