Wyklucz kapsułę podczas portowania na Mac z katalizatorem

14

Przenoszenie aplikacji do systemu Mac jest wreszcie możliwe dzięki Catalyst , problem w tym, że wiele modułów nie obsługuje AppKit. Najpopularniejszym z nich jest Crashlytics / Firebase.

In [...]/Pods/Crashlytics/iOS/Crashlytics.framework/Crashlytics(CLSInternalReport.o), building for Mac Catalyst, but linking in object file built for iOS Simulator, file '[...]/Pods/Crashlytics/iOS/Crashlytics.framework/Crashlytics' for architecture x86_64

Ponieważ jest to najnowszy temat, nie mogłem znaleźć dokumentu na temat usuwania zasobnika z mojej kompilacji dla systemu macOS, ale zachowaj go na iOS i iPadO S.

Możliwe jest użycie w kodzie:

#if !targetEnvironment(macCatalyst) 
// Code to exclude for your macOS app
#endif

Ale ta część problemu, druga część to połączenie kapsuły tylko na iOS ...

Jaki byłby najłatwiejszy / najlepszy sposób działania, gdy biblioteka nie jest niezbędna dla macOS, ale nadal jest pożądana na iOS?

AncAinu
źródło

Odpowiedzi:

12

Po odpowiedzi na @ajgryc udało mi się stworzyć eleganckie rozwiązanie:

W swoim podfile dodaj

post_install do |installer|
    installer.pods_project.targets.each do |target|
        if target.name == "Pods-[Name of Project]"
            puts "Updating #{target.name} OTHER_LDFLAGS to OTHER_LDFLAGS[sdk=iphone*]"
            target.build_configurations.each do |config|
                xcconfig_path = config.base_configuration_reference.real_path
                xcconfig = File.read(xcconfig_path)
                new_xcconfig = xcconfig.sub('OTHER_LDFLAGS =', 'OTHER_LDFLAGS[sdk=iphone*] =')
                File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
            end
        end
    end
end

Od Cocoapods 1.8.4

post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.name == "Pods-[Name of Project]"
      puts "Updating #{target.name} to exclude Crashlytics/Fabric"
      target.build_configurations.each do |config|
        xcconfig_path = config.base_configuration_reference.real_path
        xcconfig = File.read(xcconfig_path)
        xcconfig.sub!('-framework "Crashlytics"', '')
        xcconfig.sub!('-framework "Fabric"', '')
        new_xcconfig = xcconfig + 'OTHER_LDFLAGS[sdk=iphone*] = -framework "Crashlytics" -framework "Fabric"'
        File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
      end
    end
  end
end

A następnie w fazie kompilacji skryptu uruchamiania dla Fabric:

if [[$ARCHS != "x86_64"]]; then
  "${PODS_ROOT}/Fabric/run" [your usual key]
fi
AncAinu
źródło
3
Działa to dobrze, aby wyłączyć łączenie wszystkich CocoaPods w MacCatalyst. Zmień trzecią linię, if target.name.start_with?("Pods")aby złapać wszystkie cele kapsuły.
William Denniss,
Wydaje się, że to już nie działa z cocoapods 1.8.4
tmm1
1
Próbowałem w obie strony „if target.name.start_with? („ Pods ”)” nie działa dla mnie również z cocoapods 1.8.4, mam błąd poniżej, każdy może mnie poprowadzić. w /Users/ios/Desktop/xxxxxx/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector(FIRConnectorUtils_d79571aba36a7d46e5c6ca87a6fec1c1.o), budowanie pliku / pulpitu dla systemu iOS, tworzenie pliku / pulpitu dla systemu Macintosh / Desktop w systemie Macintosh /xxxxxx/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector 'dla architektury x86_64
Ankur Patel
1
Do skryptu uruchamiania można również użyć:if [[ ${IS_MACCATALYST} != "YES" ]]; then "${PODS_ROOT}/Fabric/run" fi
Honghao Zhang
Czy możesz zaktualizować odpowiedź, dodając link do problemu w strąkach kakaowych, aby osoby czytające odpowiedź mogły ją głosować? Moim zdaniem powinno to być obsługiwane od razu po wyjęciu z pudełka. github.com/CocoaPods/CocoaPods/issues/9364
KleMiX
8

Otwórz plik Pods- $ projectname.release.xcconfig w katalogu Pods projektu i zlokalizuj wiersz OTHER_LDFLAGS. Dodaj [sdk=iphone*]bezpośrednio po nazwie zmiennej (na przykład moja wygląda teraz tak):

OTHER_LDFLAGS[sdk=iphone*] = $(inherited) -ObjC -l"MailCore-ios" -l"c++" -l"iconv" -l"resolv" -l"xml2" -l"z"

To warunkowo ustawia opcje łącza tylko podczas budowania wariantów iPhone'a, zapobiegając podłączeniu zasobnika w OSX. Oczywiście, jak wspomniałeś, musi to być połączone z kodem wywołującym pod #if !targetEnvironment(macCatalyst)i #endifotaczającym go, inaczej dostaniesz błędy linkera.

To pozwoliło mi ominąć ten sam problem. (A jeśli zastanawiasz się, jakie inne fajne rzeczy oprócz zmiennych warunkowych możesz dodać do swoich plików .xcconfig, oto odnośnik, który znalazłem: https://pewpewthespells.com/blog/xcconfig_guide.html )

ajgryc
źródło
1
Dałem ci nagrodę, ale zaakceptowałem własną odpowiedź, ponieważ daję rozwiązanie od razu po wyjęciu z pudełka, które ułatwi ludziom życie, dziękuję bardzo!
AncAinu,
przepraszam, ale gdzie jest plik Pods- $ projectname.release.xcconfig. Nie jestem w stanie tego znaleźć.
Ankur Patel
W mojej konfiguracji jest to <Katalog projektów> / Pods / Docelowe pliki wsparcia / Pods- <Nazwa projektu>
ajgryc
to rozwiązanie nie jest zalecane, ponieważ xcconfig zawsze buduje się w każdym pod install. Poleciłbym przeczytać odpowiedź Fernando Moya de Rivasa na najlepszą alternatywę
Oz Shabat
6

W przypadku cocoapodów 1.8.4 musiałem dostosować doskonałą odpowiedź @ AncAinu w następujący sposób:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.name == "Pods-[Name of Project]"
      puts "Updating #{target.name} to exclude Crashlytics/Fabric"
      target.build_configurations.each do |config|
        xcconfig_path = config.base_configuration_reference.real_path
        xcconfig = File.read(xcconfig_path)
        xcconfig.sub!('-framework "Crashlytics"', '')
        xcconfig.sub!('-framework "Fabric"', '')
        new_xcconfig = xcconfig + 'OTHER_LDFLAGS[sdk=iphone*] = -framework "Crashlytics" -framework "Fabric"'
        File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
      end
    end
  end
end
tmm1
źródło
FYI, najnowsze wydanie Crashlytics jest teraz open source i dlatego w razie potrzeby kompiluje się bezpośrednio dla Catalyst. Ten hack nie jest już wymagany w przypadku Crashlytics, ale może być przydatny w przypadku innych starszych zasobników.
tmm1
w powyższej części Nazwa projektu, musimy wpisać nazwę pliku projektu? if target.name == "Pods- [MyProjectExample]”. coś takiego lub po prostu wkleić odpowiedź? bo to dla mnie nie działa
Bartu Akman
Tak, musisz zastąpić nazwą projektu.
tmm1
Zrobiłem wszystko dobrze. if target.name == "Pods- [VPNoid]" wyczyść i ponownie zbuduj mój projekt. ale wciąż narzeka błąd. Czy masz jakiś pomysł?
Bartu Akman
1
Usuń[]
tmm1
3

Mam zaktualizowane rozwiązanie, które działa dla mnie z następującymi zasobnikami Google:

  pod 'FirebaseUI/Auth'
  pod 'FirebaseUI/Phone'
  pod 'FirebaseUI/Email'
  pod 'Firebase/Auth'
  pod 'Firebase/Analytics'
  pod 'Fabric', '~> 1.10.2'
  pod 'Firebase/Crashlytics'
  pod 'Firebase/AdMob'
post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.name.start_with?("Pods")
        puts "Updating #{target.name} to exclude Crashlytics/Fabric"
      target.build_configurations.each do |config|
        xcconfig_path = config.base_configuration_reference.real_path
        xcconfig = File.read(xcconfig_path)
        xcconfig.sub!('-framework "FirebaseAnalytics"', '')
        xcconfig.sub!('-framework "FIRAnalyticsConnector"', '')
        xcconfig.sub!('-framework "GoogleMobileAds"', '')
        xcconfig.sub!('-framework "Google-Mobile-Ads-SDK"', '')
        xcconfig.sub!('-framework "GoogleAppMeasurement"', '')
        xcconfig.sub!('-framework "Fabric"', '')
        new_xcconfig = xcconfig + 'OTHER_LDFLAGS[sdk=iphone*] = $(inherited) -framework "FirebaseAnalytics"  -framework "FIRAnalyticsConnector"  -framework "GoogleMobileAds" -framework "GoogleAppMeasurement" -framework "GoogleUtilities" "-AppMeasurement" -framework "Fabric"'
        File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
      end
    end
  end
end
Andy
źródło
Próbuję użyć tego rozwiązania, ponieważ wygląda na najbardziej czyste, ale pojawia się ten błąd: ld: in /Users/<name>/source/<app>/Pods/Fabric/iOS/Fabric.framework/Fabric(Fabric.o), building for Mac Catalyst, but linking in object file built for iOS Simulator, for architecture x86_64używam dokładnie tego, co masz powyżej minus GoogleMobileAdsi Google-Mobile-Ads-SDK. Dlaczego to dostaję?
fphelp
Nie jestem pewny. W tym momencie nadszedł czas, aby usunąć tkaninę, prawda? Nie zgadzam się, że Google miał prawo je kupić, ale zrobili to i zamykają, więc ...
Andy
Niestety użycie „pod Crashlytics” automatycznie instaluje Fabric (1.10.2). Nie jestem pewien, dlaczego tak się dzieje, i jestem ostrożny przy korzystaniu z kapsuły „Firebase / Crashlytics”, ponieważ Google twierdzi, że wciąż jest w fazie beta :(
fphelp
3

Aby uzyskać najlepsze podejście do obsługi nieobsługiwanych ramek dla Catalyst, powinieneś przeczytać rozwiązanie Fernando Moya de Ri .

Po prostu powiedział, że musisz zdefiniować tablicę wszystkich bibliotek, których nie chcesz instalować na Mac OSX, w następujący sposób: ['Fabric', 'Crashlytics', 'Firebase/Core', ...] .

Następnie plik pod może wyglądać tak prosto:

# Podfile
load 'remove_unsupported_libraries.rb'
target 'My target' do
   use_frameworks!
   # Install your pods
   pod ...
end

# define unsupported pods
def unsupported_pods
   ['Fabric', 'Crashlytics', 'Firebase/Core', ...]
end

# install all pods except unsupported ones
post_install do |installer|
   configure_support_catalyst installer, unsupported_pods
end
Oz Shabat
źródło
2
Dzięki! To powinno być bardzo kompletne rozwiązanie!
WildCat