Mam app (nazwijmy go MojaApl) napisany w Swift z następującymi celami:Korzystanie Cocoapods w rozszerzeniu aplikacji za pomocą ramy
MyApp
: Głównym celemMyAppKit
: cel budowania framework dla kodu współużytkowanego między aplikacją i jej rozszerzeniami, głównie obsługa interfejsu API i obsługa bazy danych:MyAppWidget
: Widget Widget Dzisiaj (lub jakkolwiek się teraz nazywa), który wykorzystuje frameworkMyAppKit
.
ramy MyAppKit
jest związana w każdej tarczy, który wykorzystuje go, mianowicie MyApp
i MyAppWidget
. Wprowadź Cocoapods: kiedyś mieć następującą strukturę Podfile:
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
Celem tutaj było wystawiać tylko ramy MyAppKit
do innych części i nie wszystkie jej strąki (np ja nie chcę, aby móc import Alamofire
wewnątrz głównej aplikacji). Jednak począwszy od wersji RC0 Cocoapods, pod install
nie powiodło się z następującym błędem: [!] The 'Pods-MyApp' target has frameworks with conflicting names: realm and realmswift.
. Kiedyś działało, ponieważ strąki zostały zadeklarowane dla rozszerzenia, ale tylko osadzone w aplikacji hosta (zobacz this issue, aby uzyskać więcej informacji). Więc usunąłem strąki z celu widgetu, zostawiając mnie po prostu pustą linią target 'MyAppWidget'
.
Przy tej konfiguracji pod install
działa poprawnie, ale kompilacja kończy się niepowodzeniem na etapie łączenia dla celu MyAppWidget
: ld: framework not found Realm for architecture x86_64
. To może być ustalona przez jawnie dodawanie zarówno Realm.framework
i RealmSwift.framework
do sekcji „link binarne z bibliotekami” i następującym ustawieniu budować w docelowej Pods-MyAppWidget.[debug/release].xcconfig
:
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Realm" "$PODS_CONFIGURATION_BUILD_DIR/RealmSwift"`
Jednak, gdy biegnę pod install
ustawienia kompilacji są naturalnie powrócił i muszę ponownie dodać ustawienia kompilacji.
widzę następujące rozwiązania:
- Dodaj hak
post_install
dodanie tych ustawień za każdym razem, ale wydaje „hacky” i po kilku błędnych próbach znalazłem żadnego odniesienia API i nie wiem jak dodać te ustawienia do celuMyAppWidget
poprzez skrypt. Zmiana Podfile z następującą strukturę (lub nawet owinięcie go w abstrakcyjny cel):
[...] 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
Które wydaje się logiczne dla mnie w sensie „widget powinien wiedzieć, gdzie szukać podczas łączenie ale nie robi 't need strąków per se "
ale to nie dodaje wyżej wymienionych ustawień kompilacji (prawdopodobnie źle rozumiem dziedziczenie(edycja: to faktycznie działa, ale nie z celem abstrakcyjnym). Pomysł ten przyszedł mi do głowy, ponieważ w starszych wersjach CocoaPods, solution najwyraźniej dodano:search_paths
)link_with
, który jest teraz przestarzały.- Ujawnić Realm również w celu
MyApp
, jednak jest to sprzeczne z moim celem, aby nie mieć dostępu do kodu "backend" w głównym kodzie (może to być czysto estetyczne?).
Tak, oto moje pytanie: jaki jest najlepszy sposób na integrację strąków w ramach dzielonego pomiędzy głównym aplikacji i rozbudowy, a jednocześnie jest w stanie skompilować bez szczypanie wokół i ręczne dodawanie rzeczy?
Pozdrawiamy i dziękujemy z góry!
EDIT
Po Prientus' comment Mam zbadać możliwości abstrakcji i dziedziczenia. Bazowe problemy mam teraz odkryte są rzeczywiście różnorodne:
- on używany do pracy przed Cocoapods 1.2.0 ponieważ strąki zadeklarowane pod cel widgetu zostały osadzone wewnątrz aplikacji hosta jeszcze nadal związany z widgetu. Po prostu nie chce mieć kart o tej samej nazwie dla różnych celów w relacji "główna z rozszerzeniem".
- Używanie celów abstrakcyjnych jest niewystarczające, ponieważ cele nie mogą dziedziczyć tylko ścieżek wyszukiwania (
inherit! :search_paths
) z celu abstrakcyjnego. - Ścieżki wyszukiwania mogą być dziedziczone z prawdziwego celu, takiego jak
MyAppKit
, ale to ujawnia wszystkie te podpowiedzi do koduMyApp
(którego chcę uniknąć), i nadal istnieje problem łączenia ram Realm (ponieważ faktycznie widget używa najdrobniejszego kawałka gettera i dlatego go potrzebuje).
Używanie tej ostatniej opcji i ręczne łączenie Realm.framework działa, ale jest nieoptymalne pod względem moich intencji i tego, co kiedyś działało. Niektóre z tych problemów wydają się być błędem według variousissueson GitHub firmy Cocoapods. Dodałem my own issue i zaktualizuję po otrzymaniu wiadomości.
Wspomniałeś o używaniu klasy abstrakcyjnej w swoich rozwiązaniach, ale zastanawiałem się, czy faktycznie to wypróbowałeś. Masz tu bardzo dobre pytanie, które wpadłem na siebie. – Prientus
Ponadto spróbuję użyć dziedziczenia! metoda, ale cel jest zadeklarowany poza rodzicem. Zauważyłem, że składnia tutaj: https://guides.cocoapods.org/syntax/podfile.html#target i pomyślałem, że może być przydatna. – Prientus