IOS - публикация приложения watchOS Проблема CFBundleIdentifier коллизия

После загрузки приложения я получаю следующее письмо

Мы обнаружили одну или несколько проблем с недавней доставкой для вашего приложения, 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, и это вызывает проблему с дублированием идентификатора пакета.

Сервер Apple Connect обнаруживает конфликт CFBundleIdentifier при совместном использовании платформы между целевым устройством iOS и расширением Watch.

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 - единственный, присутствующий в обоих.

Я уже публиковал свое приложение много раз в прошлом без каких-либо проблем с той же конфигурацией библиотек. Я предполагаю, что Apple изменила некоторые ограничения в отношении идентификатора пакета за последние несколько дней.

Та же проблема присутствует и при использовании Карфагена.

Ответ 1

В качестве временного решения я вручную переименовал идентификатор пакета в расширении 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

Обратите внимание на переименование идентификатора пакета pods, потому что некоторые библиотеки ведут себя неправильно.

Я предлагаю переименовывать только библиотеки, отклоненные Apple, чтобы минимизировать возможные проблемы.

В настоящее время существует несколько открытых тем по этой проблеме:

Аналогичная проблема присутствует также с использованием Карфагена вместо Cocoapods

Если Apple не изменит эту новую политику в отношении идентификатора пакета, то, возможно, более чистое решение придет от команды cocoapods.

Ответ 2

Очевидно, Apple изменила процесс проверки. Похоже, они не позволяют определенным платформам в приложении иметь одинаковый идентификатор.

На форуме также есть сообщение об этом: 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

Если у вас есть несколько целей в вашем приложении, вы можете изменить цели watchOS в своей схеме в XCode и добавить .watchos к идентификатору.

Ответ 3

Вам не нужно менять каждую цель, ее очиститель, чтобы написать что-то вроде этого:

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

Ответ 4

Вот как я обошел проблему Карфагена.

1) создайте скрипт сборки Carthage, который разделяет различные фазы сборки Carthage

2) когда вы делаете реальные сборки фреймворка; сначала создайте проблемные фреймворки для iOS (у меня был только один), затем измените файлы проекта, чтобы изменить идентификатор пакета, затем создайте эти фреймворки для 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

Один из вариантов - вы можете добавить ".watchos" (abc.asd.alomofire.watchos) к идентификатору набора часов вручную.

Ответ 6

Просто удалите фазу сборки встроенных фреймворков из своего расширения.

Нажмите на расширение в целевом разделе → Этапы сборки → удалите рамки для встраивания модулей

Смотрите прикрепленное изображение:enter image description here