Исключить pod при портировании на mac с катализатором

14

Благодаря Catalyst , наконец, можно портировать приложения на Mac. Проблема в том, что многие модули не поддерживают AppKit. Наиболее распространенным был бы 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

Поскольку это недавняя тема, я не смог найти документ о том, как удалить модуль из моей сборки для macOS, но сохранил его для iOS и iPadO S.

Можно использовать в коде:

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

Но это одна часть проблемы, другая часть состоит в том, чтобы связать модуль только для iOS ...

Какой будет самый простой / лучший способ действий, когда библиотека не является жизненно важной для macOS, но все еще требуется для iOS?

AncAinu
источник

Ответы:

12

После ответа @ajgryc я смог найти изящное решение:

В вашем подфиле добавьте

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

С 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

И затем на этапе запуска сценария запуска для Fabric:

if [[$ARCHS != "x86_64"]]; then
  "${PODS_ROOT}/Fabric/run" [your usual key]
fi
AncAinu
источник
3
Это хорошо работает, чтобы отключить связывание всех CocoaPod в MacCatalyst. Измените третью строку, if target.name.start_with?("Pods")чтобы поймать все цели Pod.
Уильям Деннис
Кажется, это больше не работает с cocoapods 1.8.4
tmm1
1
Я пробовал оба способа "если target.name.start_with? (" Pods ")" не работает для меня также с cocoapods 1.8.4, я получил ошибку ниже, любой может мне помочь. в /Users/ios/Desktop/xxxxxx/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector(FIRConnectorUtils_d79571aba36a7d46e5c6ca87a6fec1c1.o), создавая файл / пользовательский файл для Mac OS Mac для Mac OSI, создавая файл для пользователей / Mac OS для Mac OSI, создавая файл для пользователей Mac OSI в Mac OSI, но создавая файл для Mac OSI для iOS /xxxxxx/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector 'для архитектуры x86_64
Анкур Патель
1
Для сценария запуска вы также можете использовать:if [[ ${IS_MACCATALYST} != "YES" ]]; then "${PODS_ROOT}/Fabric/run" fi
Хунхао Чжан
Можете ли вы обновить ответ, чтобы включить ссылку на проблему в какао-бобах, чтобы люди, читающие ответ, могли ее проголосовать? Это должно быть поддержано из коробки на мой взгляд. github.com/CocoaPods/CocoaPods/issues/9364
KleMiX
8

Откройте файл Pods- $ projectname.release.xcconfig в каталоге Pods вашего проекта и найдите строку OTHER_LDFLAGS. Добавьте [sdk=iphone*]сразу после имени переменной (как пример, мой теперь выглядит так):

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

Это условно устанавливает параметры ссылки только при создании вариантов iphone, предотвращая соединение модуля в OSX. Конечно, как вы упоминаете, это должно сочетаться с кодом, вызывающим модуль, #if !targetEnvironment(macCatalyst)и #endifокружать его, иначе вы получите ошибки компоновщика.

Это позволило мне преодолеть ту же проблему. (И если вам интересно, какие еще интересные вещи помимо условных переменных вы можете добавить в свои файлы .xcconfig, вот ссылка, которую я нашел: https://pewpewthespells.com/blog/xcconfig_guide.html )

ajgryc
источник
1
Я дал вам щедрость, но принял свой собственный ответ, поскольку я даю решение из коробки, которое облегчит жизнь людей, большое спасибо!
AncAinu
извините, но где находится файл Pods- $ projectname.release.xcconfig. Я не могу его найти.
Анкур Патель
В моем конфиге он находится в <Project Directory> / Pods / Target Support Files / Pods- <Имя проекта>
ajgryc
это решение не рекомендуется, поскольку xcconfig всегда встроен в каждый pod install. Я бы порекомендовал прочитать ответ Фернандо Мойи де Ривас за лучшую альтернативу
Оз Шабат
6

С cocoapods 1.8.4 мне пришлось адаптировать отличный ответ @ AncAinu следующим образом:

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
источник
К вашему сведению, последняя версия Crashlytics теперь имеет открытый исходный код и, таким образом, при необходимости компилируется непосредственно для Catalyst. Этот взлом больше не требуется в случае Crashlytics, но может быть полезен с другими устаревшими модулями.
tmm1
В названии части проекта выше, мы должны написать имя файла проекта? if target.name == "Pods- [MyProjectExample]". что-то подобное или просто вставить ответ? потому что это работает для меня
Барту Акман
Да, вы должны заменить название вашего проекта.
tmm1
Я все сделал правильно. если target.name == "Pods- [VPNoid]" очистить и построить мой проект снова. но все равно ошибка жалуется. У тебя есть идеи?
Барту Акман
1
Удалить[]
tmm1
3

У меня есть обновленное решение, которое работает для меня со следующими модулями 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
Энди
источник
Я пытаюсь использовать это решение, так как оно выглядит максимально чистым, но я получаю эту ошибку: 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_64я использую именно то, что у вас выше, минус GoogleMobileAdsи Google-Mobile-Ads-SDK. Почему я это получаю?
fphelp
Я не уверен. На данный момент пришло время удалить Fabric, не так ли? Я не согласен, что Google имел право купить их, но они сделали и закрывают его, так что ...
Энди
К сожалению, использование 'pod Crashlytics' автоматически устанавливает Fabric (1.10.2). Не уверен, почему это происходит, и я осторожен с использованием модуля Firebase / Crashlytics, потому что Google говорит, что он все еще находится в стадии бета-тестирования :(
fphelp
3

Чтобы лучше подходить к работе с неподдерживаемым фреймворком для Catalyst, вы, ребята, должны прочитать решение Фернандо Мойя де Ри .

Он в основном сказал , что просто нужно определить массив всех LIBS вы не хотите , чтобы установить на Mac OSX, как это: ['Fabric', 'Crashlytics', 'Firebase/Core', ...].

Тогда ваш файл pod может выглядеть так:

# 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
Спасибо! Это должно быть очень полное решение!
WildCat