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?

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

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 )


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

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

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

2
Dzięki! To powinno być bardzo kompletne rozwiązanie!
WildCat
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.