Класс X реализован как в <framework>, так и в <application>, один из двух будет использоваться, который является undefined
Я получаю это предупреждение:
Class X is implemented in both <framework> and <application> one of the two will be used, which one is undefined
Это предупреждение довольно распространено в Интернете, но я не нашел ничего, что отвечало бы конкретной проблеме, с которой я столкнулся.
Сценарий
Я создал MyFramework и MyApplication (в качестве тестового/демонстрационного приложения для MyFramework).
MyFramework использует CocoaPod (который я буду называть CoolPod), который я также хочу использовать в MyApplication (и разумно предположить, что потребитель MyFramework также будет).
Мне нужно иметь возможность распространять MyFramework как .framework(для закрытого источника). Однако это означает, что MyFramework встраивает CoolPod в свою скомпилированную библиотеку.
Теперь, когда я импортирую MyFramework и CoolPod в MyApplication, я получаю этот конфликт (выводящее предупреждение, показанное выше), поскольку классы CoolPod уже включены в библиотеку MyFramework (поскольку CoolPod встроен).
Итак, у нас есть эта структура:
CoolPod -> MyFramework \
MyApplication
CoolPod /
Вопрос
Как избежать этого конфликта?
- Есть ли способ MyApplication предоставить CoolPod для MyFramework?
- Нужно ли подключать заголовки CoolPod через MyFramework?
Я думал о включении заголовков CoolPod (но не его lib) в MyApplication, однако это кажется слишком сложным для того, что должно быть простым.
Любая помощь очень ценится, это действительно блокирует меня прямо сейчас.
Спасибо,
Индиго
Ответы
Ответ 1
Мое решение состояло в том, чтобы взять исходный код из модуля cocoa и создать для него конструкцию Touch cocoa. Затем я связал фреймворк с моим api и моим тестовым приложением.
Это не здорово, но это все, что я мог сделать быстро. Я считаю, что Cocoapods работает над поддержкой фреймворков, поэтому это решение может скоро устареть.
Моя компания также использует gradle для зависимостей (java) и сборки сценариев. Поэтому я создал задачу сборки groovy/gradle, которая создает мою фреймворк и мои поддерживающие фреймворки (рамки cocoapod) и создает из них универсальную структуру. Затем он застегивает все рамки. Это означает, что я могу распространять один почтовый индекс со всеми требованиями. Это, очевидно, не самый приятный способ распространения (мы перейдем к распространению через Cocoapods с зависимостями от наших закрытых исходных фреймворков), но он быстро настроен.
Ответ 2
Для статических библиотек с закрытым исходным кодом мы рекомендуем cocoapods-packager. Я не уверен, что это поддержка фреймворков.
Ответ 3
Одно из решений - включить use_frameworks! в рамках подфайла. Затем вы все равно можете скомпилировать свою фреймворк и вставить свою фреймворк в целевое приложение. Предупреждающие сообщения исчезнут (это просто потому, что фреймы инфраструктуры подчиняются другой структуре, но вы не вставляете ее в свое целевое приложение, а затем ваше приложение будет ссылаться на свой собственный бинарный файл.)
Но это не очень хорошее решение по двум причинам:
1. Вы должны убедиться, что целевое приложение включает необходимые модули, которые необходимы инфраструктуре.
2. Приложение может использовать другую версию модуля для фреймворка. Если оба фреймворка и приложение относятся к одному и тому же двоичному файлу, это может привести к сбою.
Я сомневаюсь, что есть хорошее решение для этой проблемы.
Ответ 4
Если вы хотите быстрое решение - просто добавьте проект MyFramework в качестве подпроекта в проект MyApplication. Вы по-прежнему можете использовать cocoa pods как для своей фреймворк, так и для тестового приложения (но включите свою "общую" lib с модулями только в проект framework)
Ответ 5
Вы можете создать Podspec для своего MyFramework
с CoolPod
в качестве зависимости.
Ваш MyFramework.podspec будет выглядеть примерно так:
Pod::Spec.new do |spec|
spec.name = 'TestFW'
spec.version = '1.0.0'
spec.license = { :type => 'BSD' }
spec.homepage = 'https://github.com/user/TestFW'
spec.authors = { 'Auther Name' => '[email protected]' }
spec.summary = 'Testing FW Pod with Test App'
spec.source = { :git => 'https://github.com/user/TestFW.git' }
spec.module_name = 'TestFW'
spec.ios.source_files = 'TestFW/*.swift'
spec.dependency 'CoolPod'
end
И ваш MyApplication
подфайл будет выглядеть примерно так:
target 'TestApp' do
use_frameworks!
pod 'CoolPod'
pod 'TestFW'
end