name: cocoapods-subspecs-organization user-invocable: false description: 用于将复杂的CocoaPods库组织成子规范。涵盖模块化架构、子规范之间的依赖管理以及默认子规范模式,以实现更好的代码组织和可选功能。 allowed-tools:
- Read
- Write
- Edit
- Bash
- Grep
- Glob
CocoaPods - 子规范组织
将复杂库组织成模块化子规范,以提高可维护性和可选功能。
什么是子规范?
子规范允许您将pod拆分为逻辑模块,可以独立安装或作为组安装。
优点
- 模块化:将核心功能与可选功能分离
- 选择性安装:用户仅安装所需部分
- 减少依赖:可选功能不强制不必要的依赖
- 更好的组织:清晰的关注点分离
基本子规范模式
Pod::Spec.new do |spec|
spec.name = 'MyLibrary'
spec.version = '1.0.0'
# 主规范没有源文件 - 所有都在子规范中
spec.default_subspecs = 'Core'
# 核心子规范 - 默认安装
spec.subspec 'Core' do |core|
core.source_files = 'Source/Core/**/*.swift'
core.frameworks = 'Foundation'
end
# 可选功能子规范
spec.subspec 'Networking' do |networking|
networking.source_files = 'Source/Networking/**/*.swift'
networking.dependency 'MyLibrary/Core' # 依赖于Core
networking.dependency 'Alamofire', '~> 5.0'
end
# 另一个可选功能
spec.subspec 'UI' do |ui|
ui.source_files = 'Source/UI/**/*.swift'
ui.dependency 'MyLibrary/Core'
ui.ios.frameworks = 'UIKit'
ui.osx.frameworks = 'AppKit'
end
end
依赖模式
子规范依赖
Pod::Spec.new do |spec|
spec.name = 'MySDK'
# 基础层
spec.subspec 'Core' do |core|
core.source_files = 'Source/Core/**/*.swift'
end
# 网络依赖于Core
spec.subspec 'Networking' do |net|
net.source_files = 'Source/Networking/**/*.swift'
net.dependency 'MySDK/Core'
net.dependency 'Alamofire', '~> 5.0'
end
# 分析依赖于Core和Networking
spec.subspec 'Analytics' do |analytics|
analytics.source_files = 'Source/Analytics/**/*.swift'
analytics.dependency 'MySDK/Core'
analytics.dependency 'MySDK/Networking'
end
end
每个子规范的外部依赖
spec.subspec 'SQLite' do |sqlite|
sqlite.source_files = 'Source/SQLite/**/*.swift'
sqlite.dependency 'MyLibrary/Core'
sqlite.dependency 'SQLite.swift', '~> 0.14'
sqlite.libraries = 'sqlite3'
end
spec.subspec 'Realm' do |realm|
realm.source_files = 'Source/Realm/**/*.swift'
realm.dependency 'MyLibrary/Core'
realm.dependency 'RealmSwift', '~> 10.0'
end
默认子规范
单一默认子规范
Pod::Spec.new do |spec|
spec.name = 'MyLibrary'
# 当用户执行: pod 'MyLibrary'
# 仅安装Core
spec.default_subspecs = 'Core'
spec.subspec 'Core' do |core|
core.source_files = 'Source/Core/**/*.swift'
end
spec.subspec 'Extensions' do |ext|
ext.source_files = 'Source/Extensions/**/*.swift'
ext.dependency 'MyLibrary/Core'
end
end
多个默认子规范
Pod::Spec.new do |spec|
spec.name = 'MySDK'
# 当用户执行: pod 'MySDK'
# 安装Core和Networking
spec.default_subspecs = 'Core', 'Networking'
spec.subspec 'Core' do |core|
core.source_files = 'Source/Core/**/*.swift'
end
spec.subspec 'Networking' do |net|
net.source_files = 'Source/Networking/**/*.swift'
net.dependency 'MySDK/Core'
end
spec.subspec 'Analytics' do |analytics|
analytics.source_files = 'Source/Analytics/**/*.swift'
analytics.dependency 'MySDK/Core'
# 可选 - 默认不安装
end
end
平台特定子规范
Pod::Spec.new do |spec|
spec.name = 'CrossPlatformLib'
# 共享核心
spec.subspec 'Core' do |core|
core.source_files = 'Source/Core/**/*.swift'
core.frameworks = 'Foundation'
end
# iOS专用子规范
spec.subspec 'iOS' do |ios|
ios.source_files = 'Source/iOS/**/*.swift'
ios.dependency 'CrossPlatformLib/Core'
ios.ios.deployment_target = '13.0'
ios.ios.frameworks = 'UIKit'
end
# macOS专用子规范
spec.subspec 'macOS' do |macos|
macos.source_files = 'Source/macOS/**/*.swift'
macos.dependency 'CrossPlatformLib/Core'
macos.osx.deployment_target = '10.15'
macos.osx.frameworks = 'AppKit'
end
end
子规范中的资源包
spec.subspec 'UI' do |ui|
ui.source_files = 'Source/UI/**/*.swift'
# 每个子规范可以有独立的资源包
ui.resource_bundles = {
'MyLibrary_UI' => [
'Resources/UI/**/*.{png,jpg,xcassets}',
'Resources/UI/**/*.{storyboard,xib}'
]
}
ui.dependency 'MyLibrary/Core'
end
spec.subspec 'Themes' do |themes|
themes.source_files = 'Source/Themes/**/*.swift'
themes.resource_bundles = {
'MyLibrary_Themes' => ['Resources/Themes/**/*']
}
themes.dependency 'MyLibrary/UI'
end
常见子规范模式
核心 + 可选功能
Pod::Spec.new do |spec|
spec.name = 'MyFramework'
spec.default_subspecs = 'Core'
# 必需核心功能
spec.subspec 'Core' do |core|
core.source_files = 'Source/Core/**/*.swift'
end
# 可选: JSON序列化
spec.subspec 'JSON' do |json|
json.source_files = 'Source/JSON/**/*.swift'
json.dependency 'MyFramework/Core'
json.dependency 'SwiftyJSON', '~> 5.0'
end
# 可选: XML支持
spec.subspec 'XML' do |xml|
xml.source_files = 'Source/XML/**/*.swift'
xml.dependency 'MyFramework/Core'
end
# 可选: 网络
spec.subspec 'Networking' do |net|
net.source_files = 'Source/Networking/**/*.swift'
net.dependency 'MyFramework/Core'
net.dependency 'Alamofire', '~> 5.0'
end
end
分层架构
Pod::Spec.new do |spec|
spec.name = 'MySDK'
# 层1: 基础
spec.subspec 'Foundation' do |foundation|
foundation.source_files = 'Source/Foundation/**/*.swift'
end
# 层2: 数据 (依赖于Foundation)
spec.subspec 'Data' do |data|
data.source_files = 'Source/Data/**/*.swift'
data.dependency 'MySDK/Foundation'
end
# 层3: 领域 (依赖于Data)
spec.subspec 'Domain' do |domain|
domain.source_files = 'Source/Domain/**/*.swift'
domain.dependency 'MySDK/Data'
end
# 层4: 表示层 (依赖于Domain)
spec.subspec 'Presentation' do |presentation|
presentation.source_files = 'Source/Presentation/**/*.swift'
presentation.dependency 'MySDK/Domain'
presentation.ios.frameworks = 'UIKit'
end
end
协议 + 实现
Pod::Spec.new do |spec|
spec.name = 'MyStorage'
# 协议定义
spec.subspec 'Core' do |core|
core.source_files = 'Source/Core/**/*.swift'
end
# UserDefaults实现
spec.subspec 'UserDefaults' do |ud|
ud.source_files = 'Source/UserDefaults/**/*.swift'
ud.dependency 'MyStorage/Core'
end
# Keychain实现
spec.subspec 'Keychain' do |keychain|
keychain.source_files = 'Source/Keychain/**/*.swift'
keychain.dependency 'MyStorage/Core'
keychain.dependency 'KeychainAccess', '~> 4.0'
end
# SQLite实现
spec.subspec 'SQLite' do |sqlite|
sqlite.source_files = 'Source/SQLite/**/*.swift'
sqlite.dependency 'MyStorage/Core'
sqlite.libraries = 'sqlite3'
end
end
用户安装模式
安装默认子规范
# 仅安装默认子规范
pod 'MyLibrary'
安装特定子规范
# 仅安装Core
pod 'MyLibrary/Core'
# 安装Core和Networking
pod 'MyLibrary/Core'
pod 'MyLibrary/Networking'
# 或更简洁地
pod 'MyLibrary', :subspecs => ['Core', 'Networking']
安装所有子规范
# 安装所有内容 (不推荐 - 臃肿依赖树)
# 无内置方式 - 用户必须列出每个子规范
嵌套子规范
spec.subspec 'Networking' do |net|
# 嵌套子规范: Networking/REST
net.subspec 'REST' do |rest|
rest.source_files = 'Source/Networking/REST/**/*.swift'
rest.dependency 'MyLibrary/Core'
end
# 嵌套子规范: Networking/GraphQL
net.subspec 'GraphQL' do |graphql|
graphql.source_files = 'Source/Networking/GraphQL/**/*.swift'
graphql.dependency 'MyLibrary/Core'
graphql.dependency 'Apollo', '~> 1.0'
end
end
# 用户安装方式:
# pod 'MyLibrary/Networking/REST'
# pod 'MyLibrary/Networking/GraphQL'
最佳实践
目录结构
MyLibrary/
├── MyLibrary.podspec
├── Source/
│ ├── Core/ # 核心子规范
│ ├── Networking/ # 网络子规范
│ ├── UI/ # UI子规范
│ └── Analytics/ # 分析子规范
├── Resources/
│ ├── Core/
│ ├── UI/
│ └── Analytics/
└── Tests/
├── CoreTests/
├── NetworkingTests/
└── UITests/
命名约定
# 使用清晰、描述性名称
spec.subspec 'Networking' # 好
spec.subspec 'Net' # 太缩写
# 分组相关功能
spec.subspec 'UI'
spec.subspec 'UIComponents'
spec.subspec 'UIExtensions'
# 需要时使用平台后缀
spec.subspec 'iOS'
spec.subspec 'macOS'
依赖指南
# 保持依赖链浅
spec.subspec 'A' do |a|
a.dependency 'MyLib/Core' # 1级 - 好
end
spec.subspec 'B' do |b|
b.dependency 'MyLib/A' # 2级 - 可以
end
spec.subspec 'C' do |c|
c.dependency 'MyLib/B' # 3级 - 考虑扁平化
end
反模式
不要
❌ 创建太多小子规范
# 过度细化
spec.subspec 'StringExtensions'
spec.subspec 'ArrayExtensions'
spec.subspec 'DictionaryExtensions'
# 更好: 分组为 'Extensions'
❌ 循环依赖
spec.subspec 'A' do |a|
a.dependency 'MyLib/B'
end
spec.subspec 'B' do |b|
b.dependency 'MyLib/A' # 循环 - 将失败
end
❌ 重复源文件
spec.subspec 'Core' do |core|
core.source_files = 'Source/**/*.swift' # 包括所有内容
end
spec.subspec 'Utils' do |utils|
utils.source_files = 'Source/Utils/**/*.swift' # 重复
end
要做
✅ 分组相关功能
spec.subspec 'Extensions' do |ext|
ext.source_files = 'Source/Extensions/**/*.swift'
end
✅ 使用清晰的依赖层次
spec.subspec 'A' do |a|
a.dependency 'MyLib/Core'
end
spec.subspec 'B' do |b|
b.dependency 'MyLib/Core' # 都依赖于Core - 好
end
✅ 保持源文件分离
spec.subspec 'Core' do |core|
core.source_files = 'Source/Core/**/*.swift'
end
spec.subspec 'Utils' do |utils|
utils.source_files = 'Source/Utils/**/*.swift'
end
测试子规范
# 验证特定子规范
pod lib lint --include-podspecs=*.podspec
# 在示例项目中测试特定子规范
cd Example
pod install
# 然后在Xcode中构建/运行
相关技能
- cocoapods-podspec-fundamentals
- cocoapods-test-specs
- cocoapods-publishing-workflow