学习组件化资源文件管理方案后的总结
起因
组件化之前,所有代码、资源文件都在主工程中,其中大量图片资源,不可避免就会出现命名冲突问题。一般情况下,我们需要一份严谨的命名规范,比如根据模块进行划分添加前缀,来避免命名冲突。
公司采用组件化方案,但是未对资源文件进行拆分,都放在主工程中,维护组件和项目非常痛苦。apple tv我们将主工程资源文件拆分到对应的Poxcode怎么编写c语言d,交由工龄差一年工资差多少组件自己管理。这样将资源文件拆分到各个Pod,使apple watch职责划分更加合理,减少外部依赖,方便xcode是什么意思独立运行。
CocoaPods提供的功能优先级是什么意思
CocoaPodsappearance提供的有use_frameworks
、static_framework
、resource
、resource_bundles
这些功能的选择,以及将其中一些功能组合使用之后资源文件的最终存储路xcode怎么编写c语言径的不同,导致使用者对图片文件、字体文件、本地化文件、其他各种文件的优先级队列种种处理方式不明所以。
组合场景下的资源文件存储路径
use_frameworks!
、static_framework
、resource_bundles
、resources
的不同组合使用,会导致资源文件的最终存放路径不同,龚俊以下是各种场景下的路径总结:
# use_frameworks! 动态库
# static_framework 静态库 podspec文件中不声明,默认为false
# resource_budles 生成独立的bundle
# resources 不生成独立的bundle,放置在.app根目录
# ---------------------------------------------------------------------------
use_frameworks!
static_framework = false
resource_bundles: .app/Frameworks/pod_name.framework/pod_name.bundle/.
resources: .app/Frameworks/pod_name.framework/.
static_framework = true
resource_bundles: .app/pod_name.bundle/.
resources: .app/.
# use_frameworks!
static_framework = false
resource_bundles: .app/pod_name.bundle/.
resources: .app/.
static_framework = true
resource_bundles: .app/pod_name.bundle/.
resources: .app/.
(.app/. 代表的app id注册是 main bundle)
不同路径下的图片取值方式及差别可以参考这篇文章:CocoaPods的资源管理和Asset Catalog优化
需要注意的是,当 Pod 中的 .x公积金cassets
类型资源文件最终存储在 main bundle 的话会和主工程的 .xcxcode修改项目名assets
文件冲突,编译会报优先级c语言错:
error: Multiple commands produce ‘/Users/gonghonglou/Library/Developer/Xcode/DerivedData/HoloResource-giqfnwiluvssbzbyvuhpkrjoewvd/Build/Products/Debug-iphonesimulator/HoloResource_Example.app/Assets.car’: 1) Target ‘HoloResource_Example’ (project ‘HoloResource’) has compile command with input ‘/Users/gonghonglouapple tv/holxcode怎么设置成中文o/HoloResource/Example/HoloResource/Images.xcassets’ 2) That command depends on command ingoogle Target ‘HoloResource_Example’ (project ‘HoloResapproveoappstoreurce’): script phase “[CP] Copy Pods Resources”
解决方法,在 Podfile 里添加:
install! 'cocoapods', :disable_input_output_paths => true
Tip: resource+不使用use_fram优先级别eworks! +assets时会编译失败,因为工程只会生成一份Assets.car
文件
Sxcode怎么运行程序howing All Messages
2022-03-26 20:42:51.046 ibtoold[25007:9169669] Lxcode怎么设置成中文aunching AssetCatalogSimulatorAgent using native architecture.
/* com.apple.actool.errors */
:宫颈癌疫苗 error: There are multiple stickers icon set or ap优先级是什么意思p icon set instances named “AppIcon”.
题外话:Xcode 10 之后引入了新的编译系统,导致xcode修改项目名 Pod 里有代码改动的话apple id密码重置无法及时编译进工程,解决方案也是上述方法。
参考:Build System Release Notes for Xcode 10
资源处理实践
图片 UIImage
public extension Resource where Base: UIImage {
/// 加载图片资源
/// - Parameters:
/// - name: 图片名
/// - bundleName: s.resource_bundles中设置的名字 一般为组件名
/// - Returns: description
static func loadImage(name: String, bundleName: String) -> UIImage? {
/// 静态库+独立bundle
var image = loadImage1(name: name, in: bundleName)
if image == nil {
/// 动态库+独立bundle
image = loadImage2(name: name, in: bundleName)
}
if image == nil {
/// 动态库+非独立bundle
image = loadImage3(name: name, in: bundleName)
}
if image == nil {
// 根目录 .app/
image = loadImage4(name: name, in: bundleName)
}
return image
}
/// 加载 .app/pod_name.bundle/.
/// - Parameters:
/// - name: 图片名
/// - bundleName: 组件名
/// - Returns: description
fileprivate static func loadImage1(name: String, in bundleName: String) -> UIImage? {
let pathComponent = "/(bundleName).bundle"
return commonLoadImage(name: name, in: pathComponent)
}
/// 加载 .app/Frameworks/pod_name.framework/pod_name.bundle/.
/// - Parameters:
/// - name: 图片名
/// - bundleName: 组件名
/// - Returns: description
fileprivate static func loadImage2(name: String, in bundleName: String) -> UIImage? {
let pathComponent = "/Frameworks/(bundleName).framework/(bundleName).bundle"
return commonLoadImage(name: name, in: pathComponent)
}
/// 加载.app/Frameworks/pod_name.framework/.
/// - Parameters:
/// - name: 图片名
/// - bundleName: 组件名
/// - Returns: description
fileprivate static func loadImage3(name: String, in bundleName: String) -> UIImage? {
let pathComponent = "/Frameworks/(bundleName).framework"
return commonLoadImage(name: name, in: pathComponent)
}
/// 加载.app/
/// - Parameters:
/// - name: 图片名
/// - bundleName: 组件名
/// - Returns: description
fileprivate static func loadImage4(name: String, in bundleName: String) -> UIImage? {
return UIImage(named: name)
}
fileprivate static func commonLoadImage(name: String, in pathComponent: String) -> UIImage? {
guard let resourcePath: String = Bundle.main.resourcePath else { return nil }
let bundlePath = resourcePath + pathComponent
let bundle = Bundle(path: bundlePath)
return UIImage(named: name, in: bundle, compatibleWith: nil)
}
}
每个组件调用 UIImage.resource.loadImage(name: "图片名", bundxcode汽车报价leName: "组件名")
就可以访问自己 bundle 里的图片了。
这里提到的四个路径做了优先级处理:
- 首先访问的是静态库 +
resource_bundles
的路径 - 其次访问的是使用
use_framewxcode修改项目名orks!
+rappreciateesource_bundleappreciates
的动态库路径 - 再次访问的是使用
use_fr优先级调度算法ameworks!
+xcode汽车报价rexcode怎么用sources
的动态库路径 - 最后appointment是 main bundle 路径
最推荐也是最合理的配置方式当然是第一种,提供静态库,使用 resource_bundles
存储资源文件。
路径 Bundle
既然图片可以通过这种方式封装,那么参照这种思路将 bundle 封装一个基础方法,有了统一的 bundle 调用方法,其他资源文件的访问就简单的多了。
public extension Resource where Base: Bundle {
/// 加载图片资源
/// - Parameters:
/// - name: 图片名
/// - bundleName: s.resource_bundles中设置的名字 一般为组件名
/// - Returns: description
static func loadBundle(in bundleName: String) -> Bundle? {
var image = loadBundle1(in: bundleName)
if image == nil {
image = loadBundle2(in: bundleName)
}
if image == nil {
image = loadBundle3(in: bundleName)
}
if image == nil {
image = loadBundle4(in: bundleName)
}
return image
}
/// 加载 .app/pod_name.bundle/.
/// - Parameters:
/// - name: 图片名
/// - bundleName: 组件名
/// - Returns: description
fileprivate static func loadBundle1(in bundleName: String) -> Bundle? {
let pathComponent = "/(bundleName).bundle"
return commonLoadBundle(in: pathComponent)
}
/// 加载 .app/Frameworks/pod_name.framework/pod_name.bundle/.
/// - Parameters:
/// - name: 图片名
/// - bundleName: 组件名
/// - Returns: description
fileprivate static func loadBundle2(in bundleName: String) -> Bundle? {
let pathComponent = "/Frameworks/(bundleName).framework/(bundleName).bundle"
return commonLoadBundle(in: pathComponent)
}
/// 加载.app/Frameworks/pod_name.framework/.
/// - Parameters:
/// - name: 图片名
/// - bundleName: 组件名
/// - Returns: description
fileprivate static func loadBundle3(in bundleName: String) -> Bundle? {
let pathComponent = "/Frameworks/(bundleName).framework"
return commonLoadBundle(in: pathComponent)
}
/// 加载.app/
/// - Parameters:
/// - name: 图片名
/// - bundleName: 组件名
/// - Returns: description
fileprivate static func loadBundle4(in bundleName: String) -> Bundle? {
return Bundle.main
}
fileprivate static func commonLoadBundle(in pathComponent: String) -> Bundle? {
guard let resourcePath = Bundle.main.resourcePath else { return nil }
let bundlePath = resourcePath + pathComponent
let bundle = Bundle(path: bundlePath)
return bundle
}
}
使用
// module_a图片名 ModuleA资源名,一般为组件名
let imagea = UIImage.resource.loadImage(name: "module_a", bundleName: "ModuleA")