Xcode 12.5.1主App与小组件扩展文件共享及双向访问问题咨询
问题核心底层限制
iOS系统中主应用与扩展是完全独立的运行进程,拥有各自独立的内存空间与沙盒。即使你把同一份Swift文件同时加入主应用和扩展的Target Membership,本质是将代码分别编译进了两个独立的二进制包,运行时两个进程中的Widget Controller是完全无关的两个实例,天然不可能直接访问另一个进程的内存数据,这也是你之前调整Target Membership始终无法达到需求的根本原因。
方案1:封装自动同步的共享数据层(无需手动触发存储)
你提到的UserDefaults/FileManager共享方案可以通过封装消除主动存储的感知,满足时间线刷新自动读取最新数据的要求:
- 首先开启主应用、小组件扩展、Intents Extension三个Target的App Groups能力,添加同一个group标识,例如
group.com.xxx.yourAppName - 对需要共享的访问逻辑做封装,对外暴露的调用接口无需感知存储逻辑,示例代码如下:
// 所有需要访问该逻辑的Target都可引用该类 public class SharedWidgetDataProvider { public static let shared = SharedWidgetDataProvider() private let groupDefaults = UserDefaults(suiteName: "group.com.xxx.yourAppName")! private let sharedContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.xxx.yourAppName")! // 示例共享属性:主应用修改时自动存储,小组件读取时直接拿最新值 public var widgetDisplayContent: String { get { groupDefaults.string(forKey: "widgetDisplayContent") ?? "" } set { groupDefaults.set(newValue, forKey: "widgetDisplayContent") } } }
- 主应用侧正常修改属性即可,无需额外调用存储方法,小组件时间线刷新时直接调用对应属性就能获取最新数据。
方案2:抽取共享Framework统一管理公共代码
如果存在大量需要跨主应用/扩展调用的公共逻辑,更规范的架构是抽离独立动态库:
- 新建iOS Framework类型的Target,命名例如
CommonCore - 将Widget Controller、公共数据模型、共享数据提供类这类需要同时被多Target访问的代码移动到
CommonCore中,需要对外暴露的类型、方法标记为public - 主应用、小组件扩展、Intents Extension三个Target都在
Build Phases - Link Binary With Libraries中添加CommonCore依赖 - 所有需要调用公共逻辑的地方只需要
import CommonCore即可,无需再维护多份Target Membership配置
内容的提问来源于stack exchange,提问作者Brian.Masse
相关产品推荐
相关产品推荐

