ITMS-90473: CFBundleVersion不匹配问题求助
我有主应用和分享扩展(Share Extension),使用fastlane进行应用分发,此前一切运行正常。近期因第三方Autopay SDK要求适配Xcode 13及以上版本,我在fastlane的archive函数中新增了配置项export_options:{ manageAppVersionAndBuildNumber: false },此后开始收到App Store Connect的提示邮件:
App Store Connect
亲爱的开发者:
我们发现您最近提交的应用“APP”1.41.0(13204)存在一处或多处问题。您的提交已成功,但建议您在下次提交时修复以下问题:
ITMS-90473: CFBundleVersion Mismatch - 扩展'APP.app/PlugIns/APP_Share.appex'的CFBundleVersion值'1'与其包含的iOS应用'APP.app'的CFBundleVersion值'13204'不匹配。
修复问题后,您可以重新上传二进制文件至App Store Connect。
此致,
App Store团队
我的prepare_for_archive函数中已通过set_info_plist_value为主应用和分享扩展的CFBundleVersion设置了相同的build_number(值取自环境变量CI_PIPELINE_ID,默认值为"1"),代码如下:
def archive(options) prepare_for_archive(options) build_ios_app( workspace: WORKSPACE, scheme: options[:scheme], clean: true, export_method: options[:adhoc] ? "ad-hoc" : "app-store", export_xcargs: "-allowProvisioningUpdates", output_directory: OUTPUT_PATH, export_options:{ manageAppVersionAndBuildNumber: false }, //❗️此处为新增配置 ) end
build_number = PIPELINE || "1" set_info_plist_value( path: INFO_PLIST_PATH, key: "CFBundleVersion", value: build_number ) set_info_plist_value( path: SHARE_INFO_PLIST_PATH, key: "CFBundleVersion", value: build_number )
此前版本号保持一致无问题,请问如何在确保Autopay SDK正常工作的前提下,让主应用与分享扩展的Build Number保持一致?
解决方案
1. 校验Info.plist路径正确性
先确认INFO_PLIST_PATH和SHARE_INFO_PLIST_PATH是否指向了项目中正确的Info.plist文件。如果分享扩展的路径因Xcode项目结构调整而失效,会导致build_number无法写入扩展的配置文件,最终出现版本号不匹配。
2. 在build_ios_app中显式传递build号
既然禁用了Xcode自动管理版本号,直接在build_ios_app参数中指定build号,同时通过xcargs传递给Xcode,确保主应用和扩展统一使用该值:
def archive(options) build_number = PIPELINE || "1" prepare_for_archive(options) build_ios_app( workspace: WORKSPACE, scheme: options[:scheme], clean: true, export_method: options[:adhoc] ? "ad-hoc" : "app-store", export_xcargs: "-allowProvisioningUpdates", output_directory: OUTPUT_PATH, export_options:{ manageAppVersionAndBuildNumber: false }, build_number: build_number, xcargs: "BUILD_NUMBER=#{build_number}" ) end
同时在Xcode中,将主应用和分享扩展的CFBundleVersion设置为$(BUILD_NUMBER),让编译时直接读取传递的参数值,避免手动修改Info.plist可能出现的路径问题。
3. 调整prepare_for_archive的执行时机
当前build_ios_app的clean: true会执行xcodebuild clean操作,虽然不会修改源文件,但可以通过pre_build钩子确保Info.plist的修改在clean之后、编译之前执行:
def archive(options) build_ios_app( workspace: WORKSPACE, scheme: options[:scheme], clean: true, export_method: options[:adhoc] ? "ad-hoc" : "app-store", export_xcargs: "-allowProvisioningUpdates", output_directory: OUTPUT_PATH, export_options:{ manageAppVersionAndBuildNumber: false }, pre_build: lambda { prepare_for_archive(options) } ) end
这样可以保证修改后的Info.plist是编译时使用的最新版本。
4. 加入日志验证修改效果
在prepare_for_archive函数中添加日志输出,确认build_number和Info.plist的修改结果:
build_number = PIPELINE || "1" puts "Current build number: #{build_number}" puts "Main app Info.plist path: #{INFO_PLIST_PATH}" puts "Share extension Info.plist path: #{SHARE_INFO_PLIST_PATH}" set_info_plist_value( path: INFO_PLIST_PATH, key: "CFBundleVersion", value: build_number ) set_info_plist_value( path: SHARE_INFO_PLIST_PATH, key: "CFBundleVersion", value: build_number ) # 验证修改结果 main_version = get_info_plist_value(path: INFO_PLIST_PATH, key: "CFBundleVersion") share_version = get_info_plist_value(path: SHARE_INFO_PLIST_PATH, key: "CFBundleVersion") puts "Main app CFBundleVersion after update: #{main_version}" puts "Share extension CFBundleVersion after update: #{share_version}"
通过日志可以快速定位是值传递错误、路径错误还是修改未生效的问题。
内容的提问来源于stack exchange,提问作者kunass2

