Использование Cocoapods в расширении приложения с помощью фреймворка
у меня есть приложение (назовем его MyApp), написанное в Swift со следующими целями:
-
MyApp
: основной элемент -
MyAppKit
: целевое построение фреймворка для кода, который совместно используется между приложением и его расширением(ов), в основном бэкэнд API и обработка базы данных -
MyAppWidget
: виджет просмотра сегодня (или как бы он ни назывался сейчас), который используетMyAppKit
основы.
на MyAppKit
основа связана на каждую цель, которая его использует, а именно MyApp
и MyAppWidget
. Введите Cocoapods: раньше у меня была следующая структура Подфайлов:
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
# Mostly UI or convenience pods
pod 'Eureka', '~> 2.0.0-beta'
pod 'PKHUD', '~> 4.0'
pod '1PasswordExtension', '~> 1.8'
end
target 'MyAppKit' do
# Backend pods for networking, storage, etc.
pod 'Alamofire', '~> 4.0'
pod 'Fuzi', '~> 1.0'
pod 'KeychainAccess', '~> 3.0'
pod 'RealmSwift', '~> 2.0'
pod 'Result', '~> 3.0'
end
target 'MyAppWidget' do
# Added here event though the target only imports MyAppKit but it worked
pod 'RealmSwift', '~> 2.0'
end
целью здесь было разоблачить только MyAppKit
рамки для других частей, а не все его стручки (например, я не хочу иметь возможность import Alamofire
внутри основного приложения). Однако, начиная с Cocoapods 1.2.0 RCs,pod install
произошли следующие ошибки : [!] The 'Pods-MyApp' target has frameworks with conflicting names: realm and realmswift.
. Он работал, потому что стручки были объявлены для расширения, но только встроенный в хост-приложение (см. этот вопрос для получения дополнительной информации). Поэтому я удалил стручки из цели виджета, оставив меня с пустым target 'MyAppWidget'
линии.
С такой конфигурацией, pod install
работает нормально, но компиляция не выполняется на этапе связывания для MyAppWidget
цель : ld: framework not found Realm for architecture x86_64
. Это можно исправить, явно добавив оба Realm.framework
и RealmSwift.framework
в раздел "связать двоичный файл с библиотеками"и следующую настройку сборки вPods-MyAppWidget.[debug/release].xcconfig
:
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Realm" "$PODS_CONFIGURATION_BUILD_DIR/RealmSwift"`
однако, когда я запустить pod install
, настройки сборки, естественно, возвращаются, и я должен добавить настройки сборки снова.
я вижу следующие решения :
- добавить
post_install
крюк, добавляющий эти настройки каждый раз, но он кажется "хакерским", и после нескольких ошибочных попыток я не нашел ссылки на API и не знаю, как добавить эти настройки вMyAppWidget
цель через скрипт. -
изменить Подфайл к следующей структуре (или даже обертывание его в абстрактную цель) :
[...] target 'MyAppKit' do # Backend pods for networking, storage, etc. pod 'Alamofire', '~> 4.0' pod 'Fuzi', '~> 1.0' pod 'KeychainAccess', '~> 3.0' pod 'RealmSwift', '~> 2.0' pod 'Result', '~> 3.0' target 'MyAppWidget' do inherit! :search_paths # Because else we get the "conflicting names" error end end
что кажется мне логичным в смысле "виджет должен знать, где искать во время связывания, но не нуждается в стручках как таковых"
но это не добавляет вышеупомянутых настроек сборки (я, вероятно, неправильно понимаю(edit: он действительно работает, но не с абстрактной целью). Эта идея пришла ко мне, потому что в более старых версиях CocoaPods решение видимо, чтобы добавить:search_paths
наследование)link_with
, который теперь устарел. - Expose Realm также в
MyApp
цель, однако это противоречит моей цели не имея доступа к "серверной" в основном коде (это может быть чисто эстетическим?).
Итак, вот мой вопрос : каков наилучший способ интегрировать стручки в рамках, разделяемых между основным приложением и расширением, все еще будучи в состоянии компилировать, без настройки вокруг и вручную добавлять вещи?
ура и спасибо заранее!
редактировать
после Prientus' я исследовал возможности абстракции и наследования. Основные проблемы, которые я сейчас обнаружил, на самом деле многообразны:
- он работал до Cocoapods 1.2.0, потому что стручки, объявленные под целью виджета, были встроены в хост-приложение, но все еще связаны с виджетом. Нет, это просто отказывается иметь стручки с одинаковым именем для разных целей в отношениях "main vs extension"
- использование абстрактных целей недостаточно, поскольку цели не могут наследовать только пути поиска (
inherit! :search_paths
) от абстрактной цели. - пути поиска могут быть унаследованы от реальной цели, такой как
MyAppKit
, но это подвергает все эти стручкиMyApp
код (которого я хочу избежать), и все еще есть проблема связывания Realm framework (потому что на самом деле виджет использует крошечный бит геттера и, следовательно, нуждается в нем).
используя эту последнюю опцию и вручную связывая область.фреймворк работает, но неоптимален в отношении моих намерений и того, что раньше работало. Некоторые из этих проблем, кажется, ошибка в соответствии с различные вопросы on Cocoapods'. Я добавил у меня вопрос и будет обновляться, когда у меня будут новости.
3 ответов
Итак, что дает :
- моя озабоченность "разделением стручков между целями" абсурдна, потому что вы все еще можете импортировать их в любом месте.
- проблема "вы должны вручную связать" исправлена простым
import RealmSwift
заявление.
таким образом, фиксированный и рабочий Подфайл:
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'Eureka', '~> 2.0.0-beta'
pod 'PKHUD', '~> 4.0'
pod '1PasswordExtension', '~> 1.8'
end
target 'MyAppKit' do
pod 'Fuzi', '~> 1.0'
pod 'RealmSwift', '~> 2.0'
pod 'Alamofire', '~> 4.0'
pod 'KeychainAccess', '~> 3.0'
pod 'Result', '~> 3.0'
target 'MyAppWidget' do
inherit! :search_paths
end
end
и это все. Я бы сказал, что старое поведение было более очевидным и не требовало чтения "целевого наследования подфайла". Я многому научился. хотя. Ура!
Я тебя не знаю. Но для меня совершенно законно и разумно иметь расширение, а хост-приложение содержит все модули, которые определяет фреймворк. И вот что я имею в виду:--4-->
def shared_pods
pod 'Alamofire'
end
target 'Framework' do
shared_pods
end
target 'Host' do
shared_pods
// Some other pods
end
target 'Extension' do
shared_pods
end
Я знаю, что вы беспокоитесь, но если вы думаете об этом, все эти сторонние фреймворки, которые вы используете, все они имеют зависимости. Вам не нужно беспокоиться о них, потому что Cocoapods заботится о них за вас. Если вы хотите использовать это, вам нужно будет поместить локальную запись pod в список.
target 'Host' do
pod Framework, :path => '../Framework'
end
но тогда вы должны поддерживать .
Это пример профиля проекта swift-3.0.
platform :ios, '8.0'
def import_public_pods
pod 'SwiftyJSON'
end
target 'Demo' do
use_frameworks!
# Pods for Demo
import_public_pods
pod 'Fabric'
pod 'Crashlytics'
target 'DemoTests' do
inherit! :search_paths
# Pods for testing
end
target 'DemoUITests' do
inherit! :search_paths
# Pods for testing
end
end
target 'DemoKit' do
use_frameworks!
# Pods for DemoKit
import_public_pods
pod 'RealmSwift'
target 'DemoKitTests' do
inherit! :search_paths
# Pods for testing
end
end