You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何在switch语句内使用#available?求多平台适配方案

在Swift Switch语句中使用#available适配iOS的解决方案

原代码的核心问题是无法直接在switch的case块中插入#available条件判断——这不符合Swift语法规范。针对EKEventStore在iOS17+/macOS13+新增的.fullAccess和.writeOnly权限状态,以下两种适配方案均无需拆分多个独立switch语句。

方案一:用where子句结合#available

直接在case后添加where条件,限制该case仅在指定系统版本生效。旧系统会自动忽略这些新case,直接走到@unknown default分支。

private func checkStatusAndGetAllEvents() -> String {
    var eventResult: String = "What?"
    let currentStatus = EKEventStore.authorizationStatus(for: .event)
    
    switch currentStatus {
    case .authorized:
        eventResult = "authorized"
    case .notDetermined:
        eventResult = "notDetermined"
        eventStore.requestAccess(to: .event) { accessGranted, error in
            // 注意:requestAccess是异步方法,原代码直接赋值eventResult不会生效
            // 需切换主线程更新,或改用闭包/async-await返回结果
            DispatchQueue.main.async {
                eventResult = accessGranted ? "notDetermined granted" : "Change Settings to Allow Access"
            }
        }
    case .restricted:
        eventResult = "restricted"
    case .denied:
        eventResult = "denied"
    // iOS17+/macOS13+专属case
    case .fullAccess where #available(iOS 17, macOS 13, *):
        eventResult = "fullAccess"
    case .writeOnly where #available(iOS 17, macOS 13, *):
        eventResult = "writeOnly"
    @unknown default:
        eventResult = "default"
    }
    
    return eventResult
}

方案二:在@unknown default中嵌套switch

若觉得where子句不够直观,可将新状态的处理逻辑放在@unknown default分支内,通过嵌套switch配合可用性检查实现适配:

private func checkStatusAndGetAllEvents() -> String {
    var eventResult: String = "What?"
    let currentStatus = EKEventStore.authorizationStatus(for: .event)
    
    switch currentStatus {
    case .authorized:
        eventResult = "authorized"
    case .notDetermined:
        eventResult = "notDetermined"
        eventStore.requestAccess(to: .event) { accessGranted, error in
            DispatchQueue.main.async {
                eventResult = accessGranted ? "notDetermined granted" : "Change Settings to Allow Access"
            }
        }
    case .restricted:
        eventResult = "restricted"
    case .denied:
        eventResult = "denied"
    @unknown default:
        if #available(iOS 17, macOS 13, *) {
            switch currentStatus {
            case .fullAccess:
                eventResult = "fullAccess"
            case .writeOnly:
                eventResult = "writeOnly"
            default:
                eventResult = "default"
            }
        } else {
            eventResult = "default"
        }
    }
    
    return eventResult
}

额外注意点

原代码中requestAccess(to:completion:)是异步方法,方法返回eventResult时,异步回调尚未执行,因此回调内的赋值不会影响返回值。若需要获取异步操作后的结果,建议改用闭包回调或async/await异步方法,示例如下:

private func checkStatusAndGetAllEvents(completion: @escaping (String) -> Void) {
    let currentStatus = EKEventStore.authorizationStatus(for: .event)
    
    switch currentStatus {
    case .authorized:
        completion("authorized")
    case .notDetermined:
        eventStore.requestAccess(to: .event) { accessGranted, error in
            DispatchQueue.main.async {
                completion(accessGranted ? "notDetermined granted" : "Change Settings to Allow Access")
            }
        }
    case .restricted:
        completion("restricted")
    case .denied:
        completion("denied")
    case .fullAccess where #available(iOS 17, macOS 13, *):
        completion("fullAccess")
    case .writeOnly where #available(iOS 17, macOS 13, *):
        completion("writeOnly")
    @unknown default:
        completion("default")
    }
}

内容的提问来源于stack exchange,提问作者iPadawan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:45:10