iOS模拟器中Swift与OC获取目录差异原因及解决方法
React Native Async Storage通过Objective-C方法NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES).firstObject在iOS模拟器中获取的目录为:
~/Library/Developer/CoreSimulator/Devices/6A36BEDF-71DA-4A9B-9CDD-EBC6BCE11BC0/data/Containers/Data/Application/D258BA62-85FF-4288-95BF-D1318C63B947/Library/Application Support/
但在同一款React Native iOS应用的SwiftUI Widget扩展中,调用FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first得到的目录为:
/Users/brandon/Library/Developer/CoreSimulator/Devices/6A36BEDF-71DA-4A9B-9CDD-EBC6BCE11BC0/data/Library/Application Support/
两者路径存在差异,请问为何Swift方法返回不同目录,如何修改使其获取到OC方法对应的目录?期望Swift代码返回结果与React Native Async Storage的OC实现一致。
这是因为主应用和Widget扩展属于两个独立的沙盒容器:
- React Native主应用作为标准iOS App,它的
Application Support目录位于自身的应用沙盒内部(Containers/Data/Application/[AppUUID]/Library/Application Support/),这是iOS App的默认沙盒结构。 - Widget扩展是独立的扩展进程,默认情况下它的沙盒与主应用隔离,使用
.userDomainMask获取的是扩展自身沙盒根目录下的Application Support,而非主应用的容器目录。
要让Widget获取到主应用Async Storage使用的目录,推荐使用iOS官方的应用组(App Groups) 实现跨容器数据共享,具体步骤如下:
1. 配置应用组
- 登录Apple开发者后台,为你的App ID添加应用组(例如
group.com.yourcompany.yourapp)。 - 在Xcode中,分别为主应用和Widget扩展的
Signing & Capabilities页面添加App Groups能力,并勾选创建好的应用组。
2. 修改React Native Async Storage的存储路径
修改iOS端Async Storage的OC实现,将数据存储到应用组共享目录:
// 替换原有路径获取逻辑 NSString *appGroupID = @"group.com.yourcompany.yourapp"; NSURL *groupContainerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:appGroupID]; NSString *appSupportPath = [groupContainerURL.path stringByAppendingPathComponent:@"Library/Application Support"]; // 使用该路径初始化Async Storage
3. 在Widget中获取共享目录
修改Swift代码,通过应用组ID获取共享容器路径:
let appGroupID = "group.com.yourcompany.yourapp" if let groupContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupID) { let targetAppSupportURL = groupContainerURL.appendingPathComponent("Library/Application Support") // targetAppSupportURL 即为与主应用Async Storage一致的目录 }
补充说明
不建议通过硬编码主应用UUID的方式定位目录,因为App重装后UUID会变化,导致路径失效。应用组是iOS官方支持的稳定跨进程共享方案,也是此类场景的标准解决方案。
内容的提问来源于stack exchange,提问作者Brandon Pelton-Cox

