Swift framework中无需宿主应用名即可使用图片资源的实现方法
Swift Framework 内加载Assets资源(无宿主名称依赖方案)
之前搜到的需要预先知晓宿主应用名称的实现方案,本质是走错了资源定位的起点——从宿主的mainBundle反向寻找framework的资源路径,才需要拼接宿主名称、Bundle ID这类信息。正确的实现完全可以做到不感知宿主App的任何名称信息,具体步骤如下:
核心实现步骤
- 资源归属配置:把framework对应的
.xcassets资产目录,添加为framework自身target的编译资源,确保资产会被打包到framework的私有资源包内,不要把framework用到的图片资源放到宿主App的target下。 - 自定义Bundle定位逻辑:不要使用默认的
UIImage(named: "图片名")方法(该方法默认从宿主App的mainBundle加载资源),在framework内部写统一的Bundle定位扩展,从framework自身的代码位置反查资源包路径:extension Bundle { /// 定位framework自身的资源Bundle static var currentFrameworkResource: Bundle { // 以framework内的自有类为锚点,拿到类所在的framework主Bundle // 这里替换成你framework内任意一个实际存在的类即可 let mainFrameworkBundle = Bundle(for: FrameworkImageLoader.self) // 匹配编译生成的同名资源Bundle if let resourcePath = mainFrameworkBundle.path(forResource: "你的Framework名称", ofType: "bundle"), let resourceBundle = Bundle(path: resourcePath) { return resourceBundle } // 兼容SPM、CocoaPods下资源直接打包在主Bundle的场景 return mainFrameworkBundle } } - 图片加载逻辑:用上面自定义的资源Bundle初始化图片,全程不需要读取mainBundle的任何路径信息:
let image = UIImage(named: "资源内的图片名称", in: .currentFrameworkResource, compatibleWith: nil)
常见适配提醒
- 这套逻辑在动态framework、静态framework、SPM包、CocoaPods私有库场景下都可以通用,只要正确配置了资源归属,不管宿主App叫什么、是什么应用,资源定位都不会失效。
- 注意不要让framework的资产目录和宿主App的资产目录出现同名图片,否则可能出现资源加载冲突,最好在framework的资产目录下做独立的命名空间分类。
- 不需要手动拼接任何和宿主应用相关的路径字符串,完全规避了宿主名称变更、应用重命名导致的资源加载失败问题。
内容的提问来源于stack exchange,提问作者Swift lover
相关产品推荐
相关产品推荐

