iOS - watchOS应用程序发布问题CFBundleIdentifier冲突

14

在上传应用之后,我收到了以下电子邮件:

我们发现您的应用程序 XXX 最近的上传存在一个或多个问题。请纠正以下问题,然后重新上传。

ITMS-90806: CFBundleIdentifier冲突 - 每个捆绑包必须具有唯一的捆绑标识符。捆绑标识符“org.cocoapods.CocoaLumberjack”在以下捆绑包中使用:'[CocoaLumberjack.framework, CocoaLumberjack.framework]'。

CocoaLumberjack是一个第三方库,我以前已经多次使用它而没有任何问题,我很困惑。

这与框架的.plist关键字CFBundlePackageType无关,如此问题/答案所指出的那样:Framework CFBundleIdentifier Collision。CocoaLumberjack捆绑包类型为“Framework”(CFBundlePackageType = FMWK)。CocoaLumberjack是一个广泛使用的第三方库,通过cocoapods添加到我的项目中。

这个问题可能与我的应用程序捆绑包中的watchOS目标有关。CocoaLumberjack库用于iOS应用和watchOS应用,并导致捆绑标识符重复的问题。

如果在iOS目标和Watch扩展之间共享框架,则Apple Connect服务器将检测到CFBundleIdentifier冲突。

target 'App' do
 platform :ios, '9.0'
 # Pods for App
 ...
 pod 'CocoaLumberjack/Swift', '~> 3.5.3'
 ...
end

target 'AppWatch Extension' do
 platform :watchos, '5.0'
 # Pods for Watch Extension
 ...
 pod 'CocoaLumberjack/Swift', '~> 3.5.3'
 ...
end

iOS应用程序正在使用该库,watchOS扩展程序也正在使用同一库。它们使用的是不同的库,但CocoaLumberjack是两者都包含的唯一一个库。

我已经多次使用相同的库配置发布了我的应用程序,并且之前从未出现任何问题。我猜测苹果在最近几天内更改了有关bundle identifier的某些限制。

使用Carthage也存在同样的问题。

6个回答

9
作为一个临时解决方案,我手动重命名了watchOS扩展的绑定标识符,然后应用程序发布正常工作,但这并不是一个好的解决方案,特别是如果您在CI系统上运行构建。
更好的选择是在pod文件中添加特定的后安装操作。
post_install do |installer|
 installer.pods_project.targets.each do |target|
  if target.name == 'CocoaLumberjack-watchOS'
   target.build_configurations.each do |config|       
    config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}-$(PLATFORM_NAME)'
   end
  end
 end
end

或者,如果您需要处理多个库:
post_install do |installer|
 watchosLibs = ['Lib1-watchOS', 'Lib2-watchOS', 'Lib3-watchOS']
 installer.pods_project.targets.each do |target|
  if watchosLibs.include? target.name
   target.build_configurations.each do |config|
    config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}.${PLATFORM_NAME}"
   end
  end
 end
end

请注意重命名Pod的bundle标识符,因为否则某些库可能无法正常工作。我建议仅重命名被Apple拒绝的库,以最小化可能出现的问题。目前有一些关于此问题的不同开放线程:

使用Carthage而不是Cocoapods也存在类似的问题:

如果苹果不改变这个新的bundle标识符政策,那么更清晰的解决方案可能会来自Cocoapods团队。


我看到苹果论坛上整个讨论主题被管理员拒绝了。所以它不再可用。幸运的是,我们可以在这里继续谈论它 :-) - cristallo

8
显然,苹果公司修改了验证过程。看起来他们不允许应用程序中的特定于平台的框架具有相同的标识符。
论坛上也有一篇帖子涉及此问题:https://forums.developer.apple.com/thread/122048 如果您因使用Cocoapods而遇到此问题,您可以修补Podfile以将平台名称附加到包标识符中,以使它们始终保持唯一性(来源):
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}-$(PLATFORM_NAME)'
    end
  end
end

如果您的应用程序有多个目标,您可以在XCode中更改方案中的watchOS目标,并将 .watchos 附加到标识符末尾。


1
我在苹果论坛上发了个帖子:我仍在努力理解哪种解决方案是最好的,同时关于更改bundle名称的解决方法看起来很不错。 - cristallo
2
请注意重命名所有的Pods包标识符,因为否则有些Pods可能无法正常工作。例如:一些人在使用Firebase时遇到了问题,原因是脚本已经重命名了它的包标识符。我建议只重命名被苹果拒绝的那些。 - cristallo
1
苹果刚刚批准了我们的应用程序更新,该更新使用了我回答中描述的技术。 - Tieme
我并不是说这种处理方式是错误的,因为它确实是正确的 :-) ... 只是要注意,并不是每个库都能正常工作。 - cristallo
当我尝试在实施此方法后归档构建时,我遇到了以下错误: “无效的代码签名标识符。您的代码签名中的标识符必须与其捆绑标识符匹配。” - Zachary Bell

1
您不需要更改每个目标,编写以下内容即可使代码更简洁:
post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.platform_name == :watchos
      target.build_configurations.each do |config|
        config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}-$(PLATFORM_NAME)'
      end
    end
  end
end

0

其中一种选择是 - 您可以手动将 ".watchos"(abc.asd.alomofire.watchos) 添加到手表 Bundle Identifier 中。


0
这是我已经解决 Carthage 问题的方法。
1)创建一个 Carthage 构建脚本,将不同的 Carthage 构建阶段分开处理。
2)当你进行实际的框架构建时,先为 iOS 构建有问题的框架(我只有一个),然后修改你的项目文件以更改 bundle identifier,接着为 watchOS 构建这些框架,最后构建其余的框架。
carthage bootstrap --no-checkout
carthage checkout
#undo previous CFBundleIdentifier changes
sed -i '' 's/com.someco.MyFramework.watchOS;/com.someco.MyFramework;/g' Carthage/Checkouts/MyFramework/MyFramework.xcodeproj/project.pbxproj
carthage build --cache-builds --platform iOS
#set a unique CFBundleIdentifier
sed -i '' 's/com.someco.MyFramework;/com.someco.MyFramework.watchOS;/g' Carthage/Checkouts/MyFramework/MyFramework.xcodeproj/project.pbxproj
carthage build --no-use-binaries --platform watchOS --configuration $CONF $VERBOSE MyFramework


-5

只需从您的扩展中删除嵌入式框架构建阶段即可。

在目标部分中单击扩展 -> 构建阶段 -> 删除嵌入式Pods框架

请参见附图:enter image description here


1
如果我删除嵌入框架操作,那么扩展应用程序将不再工作,因为它无法找到库。 - cristallo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接