使用催化剂移植到 mac 时排除 pod
Posted
技术标签:
【中文标题】使用催化剂移植到 mac 时排除 pod【英文标题】:Exclude pod when porting to mac with catalyst 【发布时间】:2020-02-26 08:59:14 【问题描述】:多亏了 Catalyst,终于可以将应用程序移植到 mac,但问题是,许多 pod 不支持 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 构建中删除 pod 但保留它用于 iOS 和 iPadO 的文档S。
可以在代码中使用:
#if !targetEnvironment(macCatalyst)
// Code to exclude for your macOS app
#endif
但是那一部分的问题,另一部分是只为iOS链接pod...
当库对 macOS 并不重要但在 iOS 上仍然需要时,最简单/最好的做法是什么?
【问题讨论】:
嘿嘿!很高兴知道我的回答是否对您有所帮助!如果是,请将答案标记为正确答案 【参考方案1】:对于为 Catalyst 处理不支持的框架的最佳方法,你们应该阅读 Fernando Moya de Rivas 的解决方案,他有一个 github 和解决方案 here 以及更多最新信息。
他基本上说你只需要定义一个你不想在 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 catalyst_unsupported_pods
['Fabric', 'Crashlytics', 'Firebase/Core', ...]
end
# Remove unsupported pods from your project
post_install do |installer|
installer.configure_support_catalyst
end
【讨论】:
我认为这应该是现在公认的答案。请注意,我认为它需要 Ruby 2.6.3 才能在调用filter
时避免错误
我现在将其切换为已接受的答案,因为这似乎是共识:)【参考方案2】:
根据这里已经讨论过的内容...这是我针对具有多个目标的项目的解决方案。它基本上是在验证每个目标上的库的使用情况,而不是遵循目标名称。
post_install do |installer|
installer.pods_project.targets.each do |target|
# handle non catalyst libs
libs = ["FirebaseAnalytics", "Google-Mobile-Ads-SDK"]
target.build_configurations.each do |config|
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
values = ""
libs.each |lib|
if xcconfig["-framework \"#lib\""]
puts "Found '#lib' on target '#target.name'"
xcconfig.sub!(" -framework \"#lib\"", '')
values += " -framework \"#lib\""
end
if values.length > 0
puts "Preparing '#target.name' for Catalyst\n\n"
new_xcconfig = xcconfig + 'OTHER_LDFLAGS[sdk=iphone*] = $(inherited)' + values
File.open(xcconfig_path, "w") |file| file << new_xcconfig
end
end
end
end
它输出类似这样的东西
Generating Pods project
Found 'Google-Mobile-Ads-SDK' on target 'Pods-TheApp'
Found 'FirebaseAnalytics' on target 'Pods-TheApp'
Preparing 'Pods-TheApp' for Catalyst
Found 'Google-Mobile-Ads-SDK' on target 'Pods-TheApp-TheAppTests'
Found 'FirebaseAnalytics' on target 'Pods-TheApp-TheAppTests'
Preparing 'Pods-TheApp-TheAppTests' for Catalyst
Found 'Google-Mobile-Ads-SDK' on target 'Pods-TheApp-TheApp_iOS_UI_Tests'
Found 'FirebaseAnalytics' on target 'Pods-TheApp-TheApp_iOS_UI_Tests'
Preparing 'Pods-TheApp-TheApp_iOS_UI_Tests' for Catalyst
Found 'Google-Mobile-Ads-SDK' on target 'Pods-TheAppIntentsExtension'
Found 'FirebaseAnalytics' on target 'Pods-TheAppIntentsExtension'
Preparing 'Pods-TheAppIntentsExtension' for Catalyst
Found 'Google-Mobile-Ads-SDK' on target 'Pods-TheAppTodayExtension'
Found 'FirebaseAnalytics' on target 'Pods-TheAppTodayExtension'
Preparing 'Pods-TheAppTodayExtension' for Catalyst
【讨论】:
【参考方案3】:我有一个更新的解决方案,适用于以下 Google pod:
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
。为什么我会得到这个?
我不确定。此时是时候移除 Fabric 了,不是吗?我不同意 Google 有权购买它们,但他们确实并且正在关闭它,所以......
遗憾的是,使用“pod Crashlytics”会自动安装 Fabric (1.10.2)。不知道为什么会发生这种情况,并且对使用“Firebase/Crashlytics”吊舱持谨慎态度,因为谷歌表示它仍处于测试阶段:(
执行此操作时,是否有人因错误“捆绑根目录中存在未密封的内容”而导致构建失败?
@user13138159 我正在尝试上述解决方案,但它给了我错误 ld: in /Users/按照@ajgryc 的回答,我能够做出一个时尚的解决方案:
在你的 podfile 中添加
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
【讨论】:
这可以很好地禁用所有 CocoaPods 在 MacCatalyst 中的链接。将第三行更改为if target.name.start_with?("Pods")
以捕获所有 Pod 目标。
这似乎不再适用于 cocoapods 1.8.4
我尝试了两种方式“如果 target.name.start_with?("Pods")” 也不适用于 cocoapods 1.8.4,我得到以下错误,任何人都可以指导我。在 /Users/ios/Desktop/xxxxxx/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector(FIRConnectorUtils_d79571aba36a7d46e5c6ca87a6fec1c1.o) 中,为 Mac Catalyst 构建,但在为 iOS 模拟器构建的目标文件中链接,文件 '/Users/ios/Desktop /xxxxxx/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector' 用于架构 x86_64
运行脚本也可以使用:if [[ $IS_MACCATALYST != "YES" ]]; then "$PODS_ROOT/Fabric/run" fi
您能否更新答案以在可可豆荚中包含指向问题的链接,以便阅读答案的人可以对其进行投票?在我看来,这应该得到开箱即用的支持。 github.com/CocoaPods/CocoaPods/issues/9364【参考方案5】:
使用 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
【讨论】:
仅供参考,最新版本的 Crashlytics 现在是开源的,因此可以在需要时直接为 Catalyst 编译。对于 Crashlytics,此 hack 不再需要,但可用于其他旧 pod。 在上面的项目名称部分,我们必须写项目文件的名称吗?如果 target.name == "Pods-[MyProjectExample]"。类似的东西还是只是粘贴答案?因为它不适合我 是的,你必须用你的项目名称替换。 我做对了。 if target.name == "Pods-[***oid]" clean 并再次构建我的项目。但仍然有错误在抱怨。你有什么想法吗? 删除[]
【参考方案6】:
打开项目 Pods 目录中的 Pods-$projectname.release.xcconfig 文件,并找到 OTHER_LDFLAGS 行。在变量名后立即添加[sdk=iphone*]
(例如,我的现在看起来像这样):
OTHER_LDFLAGS[sdk=iphone*] = $(inherited) -ObjC -l"MailCore-ios" -l"c++" -l"iconv" -l"resolv" -l"xml2" -l"z"
这仅在构建 iphone 变体时有条件地设置链接选项,防止 pod 在 OSX 上链接。当然,正如您所提到的,这需要与调用 pod 的代码周围的 #if !targetEnvironment(macCatalyst)
和 #endif
结合使用,否则您将收到链接器错误。
这让我克服了同样的问题。 (如果你想知道除了条件变量之外还有什么很酷的东西可以添加到你的 .xcconfig 文件中,这里是我找到的参考:https://pewpewthespells.com/blog/xcconfig_guide.html)
【讨论】:
我已经给了你赏金,但我接受了我自己的答案,因为我提供了一个开箱即用的解决方案,这将使人们的生活更轻松,非常感谢! 抱歉,Pods-$projectname.release.xcconfig 文件在哪里。我找不到它。 在我的配置中,它位于pod install
中构建自己。我建议阅读this Fernando Moya de Rivas's answer 以获得最佳选择以上是关于使用催化剂移植到 mac 时排除 pod的主要内容,如果未能解决你的问题,请参考以下文章
当基于场景的文档mac催化剂应用程序在应用程序重启时重新打开窗口时如何避免奇怪的行为?
将 Mac 催化剂二进制文件上传到 App Store 连接时出现问题