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

SwiftUI Widget扩展如何访问UIKit主项目的结构体、枚举等代码资源

问题根因

Widget 扩展属于独立的 Extension Target,和主 App Target 运行在完全隔离的沙箱与进程中,二者默认处于编译隔离状态,你无法直接通过导入主 App 模块的方式访问主 Target 内的代码,之前导入 MyApp 模块后依然无法访问的问题就是由该架构隔离规则导致的。

解决方案(按推荐优先级排序)

方案1:抽取公共代码到共享框架(官方推荐,长期维护成本最低)

这是苹果官方建议的跨 Target 代码复用方案,操作步骤如下:

  • 在 Xcode 中新建一个 Framework 类型的 Target,可命名为类似 MyAppCore
  • 将需要在主 App 和 Widget 中同时使用的模型结构体、枚举、工具类,从主 Target 的成员资格中移除,改为勾选 MyAppCore 的 Target 成员资格
  • 所有抽入 MyAppCore 的类型、方法、属性,都需要加上 public(按需选择 open)访问控制修饰符,同时要手动添加公开的初始化方法,示例如下:
// 原主项目中声明的模型
struct UserModel {
    let name: String
    let avatar: String
}

// 抽入 MyAppCore 后的声明
public struct UserModel {
    public let name: String
    public let avatar: String
    public init(name: String, avatar: String) {
        self.name = name
        self.avatar = avatar
    }
}
  • 分别进入主 App Target 和 Widget Extension Target 的 General - Frameworks, Libraries, and Embedded Content 配置项,添加 MyAppCore 依赖
  • 后续在主 App 和 Widget 的代码中,只要导入 import MyAppCore 即可访问所有共享的公共代码

方案2:直接勾选 Target 成员资格(适合小型项目快速验证)

如果项目规模较小,不想额外维护独立框架,可以使用更轻量的实现方式:

  • 选中需要给 Widget 复用的文件,打开 Xcode 右侧的检查器面板,找到 Target Membership 配置项
  • 除原有主 App Target 外,额外勾选你的 Widget Extension Target 即可
  • 该方式不需要导入任何额外模块,直接即可在 Widget 中访问对应类型,缺点是后续新增其他扩展(如 Watch 扩展、灵动岛扩展等)时需要重复勾选,代码复用管理成本会随项目迭代上升。
注意事项
  • 共享代码中不能包含主 App 独有的、扩展禁用的 API(比如 UIApplication.shared),否则会触发编译报错
  • 如果需要在主 App 和 Widget 之间同步运行时数据,不能使用默认的 UserDefaults.standard,需要通过配置 App Group 实现共享存储。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:36:04