如何通过CocoaPods仅为iOS设备而非模拟器添加Podspec依赖
问题场景
我维护着MyParentModule的podspec,MyApp依赖这个模块。需求是让MyParentModule只在iOS真机上依赖MyModule,模拟器构建时不需要这个依赖。但直接用s.dependency 'MyModule'会同时给真机和模拟器都加上依赖,不符合要求。
之前的尝试
我曾试图通过XCConfig手动配置路径和链接标志来实现:
s.pod_target_xcconfig = { 'FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*]' => '$(inherited) ${PODS_CONFIGURATION_BUILD_DIR}/MyModule', 'OTHER_LDFLAGS[sdk=iphoneos*]' => '$(inherited) -framework MyModule' }
代码里也做了条件导入:
#if !targetEnvironment(simulator) import MyModule #endif
模拟器运行没问题,但真机调用时直接崩溃,报错找不到MyModule:
Referenced from: '/private/var/containers/Bundle/Application/F947DD90-5ADD-4DE3-B2D0-9ED12BFD5CF8/MyApp.app/Frameworks/MyParentModule.framework/MyParentModule'
Reason: tried: '/usr/lib/swift/MyModule.framework/MyModule' (no such file), '/private/var/containers/Bundle/Application/F947DD90-5ADD-4DE3-B2D0-9ED12BFD5CF8/MyApp.app/Frameworks/MyModule.framework/MyModule' (no such file), '/private/var/containers/Bundle/Application/F947DD90-5ADD-4DE3-B2D0-9ED12BFD5CF8/MyApp.app/Frameworks/MyParentModule.framework/Frameworks/MyModule.framework/MyModule' (no such file), '/usr/lib/swift/MyModule.framework/MyModule' (no such file), '/usr/lib/swift/MyModule.framework/MyModule' (no such file), '/private/var/containers/Bundle/Application/F947DD90-5ADD-4DE3-B2D0-9ED12BFD5CF8/MyApp.app/Frameworks/MyModule.framework/MyModule' (no such file), '/private/var/containers/Bundle/Application/F947DD90-5ADD-4DE3-B2D
问题根源
手动改XCConfig的方式绕开了CocoaPods的依赖管理逻辑,CocoaPods没有把MyModule纳入构建流程,导致真机打包时MyModule没有被复制到App的Frameworks目录里,运行时自然找不到。
正确配置方式
直接用CocoaPods自带的平台特定依赖语法,让CocoaPods自动处理依赖的构建和集成:
- 修改
MyParentModule的podspec,仅给iOS真机添加依赖:
# 仅在iOS真机目标中引入MyModule s.dependency 'MyModule', :platforms => { :ios => { :sdk => 'iphoneos*' } }
如果需要指定配置环境(比如Debug/Release),可以这样写:
s.ios.dependency 'MyModule', :configurations => ['Debug', 'Release'], :conditions => { :sdk => 'iphoneos*' }
删除之前手动添加的
FRAMEWORK_SEARCH_PATHS和OTHER_LDFLAGS配置,CocoaPods会自动处理依赖的路径和链接。代码中的条件导入保留,确保模拟器编译时不会引用MyModule:
#if !targetEnvironment(simulator) import MyModule #endif
这样配置后,CocoaPods会在构建真机目标时自动拉取、编译并打包MyModule,模拟器构建则完全忽略该依赖,既满足需求又不会出现运行时崩溃。
内容的提问来源于stack exchange,提问作者Aswath

