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

如何在WidgetBundle中添加iOS16 Lock Screen Widget并兼容iOS15

编译失败原因

@WidgetBundleBuilder 是苹果为Widget容器实现的结果构建器,原生不支持直接在构建闭包内书写#available版本判断的if-else分支,示例代码中的空else分支和未做可用性包装的高版本Widget,会导致构建器无法正确解析语法,最终触发编译错误。

正确实现方式

核心思路是给仅支持iOS16+的锁屏Widget添加显式系统版本标记,删除WidgetBundle内空的else分支,不需要额外修改项目的iOS15部署目标,参考代码如下:

方案1:封装高版本Widget组(推荐)

// 给仅支持高版本的组件封装一层,添加明确的可用性标记
@available(iOSApplicationExtension 16.0, *)
struct LockScreenWidgets: Widget {
    var body: some WidgetConfiguration {
        LockScreenRecoveryScoreWidget().body
        // 后续新增的iOS16+锁屏Widget都可以加在这里
    }
}

struct SecondExtraBundle: WidgetBundle {
    @WidgetBundleBuilder
    var body: some Widget {
        // 原有兼容iOS15的Widget不受影响
        DailyHeartRatesWidget()
        // 版本判断不需要写空else分支,低版本系统会自动忽略该块
        if #available(iOSApplicationExtension 16.0, *) {
            LockScreenWidgets()
        }
    }
}

方案2:直接给高版本Widget加可用性标记

如果不想额外封装分组,也可以直接给锁屏Widget本身添加系统版本限制:

// 直接对锁屏Widget声明系统版本要求
@available(iOSApplicationExtension 16.0, *)
extension LockScreenRecoveryScoreWidget: Widget { }

struct SecondExtraBundle: WidgetBundle {
    @WidgetBundleBuilder
    var body: some Widget {
        DailyHeartRatesWidget()
        if #available(iOSApplicationExtension 16.0, *) {
            LockScreenRecoveryScoreWidget()
        }
    }
}
注意事项
  • 禁止在@WidgetBundleBuilder闭包内书写空的else分支,会导致构建器无法匹配对应构建方法
  • 所有仅支持iOS16+的组件必须显式标注@available(iOSApplicationExtension 16.0, *),避免低版本系统链接高版本API触发崩溃
  • 不要给整个WidgetBundle的body属性添加高版本可用性标记,会导致原有兼容iOS15的Widget在低版本系统下无法加载

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:31:09