在 switch 语句中检查可用性

19

如果一个Enum类型在新的操作系统版本中添加了新的case,如何在switch语句中检查其可用性? 就像下面的StoreKit中的Enum一样

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
}

以下代码是唯一的解决方案吗?它太冗余了。

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-------------------------

我认为这不是一个问题。在一个switch语句中编写所有情况是可以的,if语句是不必要的,因为新添加的情况在低版本的iOS中不会被调用。

3个回答

6
通常这种情况发生在使用最新的SDK和工具链的Xcode上。例如,Xcode 12附带了iOS 14 SDK和Swift 5.3,并且与新案例(如PHAuthorizationStatus.limited)存在类似问题。该问题被标记为仅在iOS 14中可用,它将破坏没有default case的switch语句。
为了解决Xcode 11和Xcode 12的版本兼容性问题,建议采用以下解决方案来检查Swift版本:
    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()
    }

1
遇到了与将 .Mac 添加到 UIUserInterfaceIdiom 枚举的问题。使用此方法使其在 Xcode11 上编译(因为团队中的大多数人仍在使用它),并在 Xcode12 上进行测试 iOS14 功能。 - pbush25

3
我想你可以这样做:

我想你可以这样做:

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
            }
        }
    }

如果没有default case,你无法编写完整的switch语句,但是也不会有冗余代码。


-1

这个怎么样?

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 {

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接