为什么当我的框架被导入到其他地方时,我作为可选链接的 iOS 个框架被视为必需的?

Why are iOS frameworks I'm linking as Optional being treated as required when my framework is imported elsewhere?

我正在尝试向我公司发布的现有 iOS 框架添加功能。新功能要求我们使用许多其他第三方提供的框架。我们希望确保我们的客户在不想激活新功能时不需要部署这些框架。

当我在我自己的框架的 Target / General / Linked Frameworks and Libraries 部分引用它们时,我将这些框架中的每一个都配置为可选。我还在我的框架的 Target / Build Phases / Link Binary With Libraries 部分将它们标记为可选。我希望这意味着当这些框架不存在时,我的框架可以导入到 xcodebuild 中。

这在我构建框架的机器上有效,但是一旦其他人试图将他们的 Xcode 对象导入到导入语句中,并带有消息 "Missing required module 'x'"(其中 x是我的框架导入的顶级第三方框架。

我尝试删除它们并向构建中添加形式为“-weak_framework {name}”的链接器指令,但我可以从 xcodebuild 日志中看到可选设置只是简单地生成这些,而且更方便.

我的框架使用 Swift 5,以防相关。

我错过了什么?

非常感谢您提供任何线索。

如果您创建自己的框架并使用第三方框架,并且您想让这些第三方框架成为可选的(但同时只需要框架的某些功能),那么我认为您需要做一些事情.

首先确保那些应该是可选的第三方框架使用 -weak_framework 选项进行链接。看来你已经这样做了。如果您要使用 cocoapods 添加那些第三方框架,那么您可能需要在 Podfile 脚本的末尾添加如下所示,因为 cocoapods 往往会覆盖这些更改并将 -weak_framework 恢复为 -framework 如果您手动进行了更改。

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
        xcconfig_path = config.base_configuration_reference.real_path
        xcconfig = File.read(xcconfig_path)
        xcconfig_mod = xcconfig.gsub(/-framework "ThirdPartyFrameworkName"/, "-weak_framework \"ThirdPartyFrameworkName\"")
        File.open(xcconfig_path, "w") { |file| file << xcconfig_mod }
    end
  end
end

第二件事是您需要在您的框架中导入这个第三方框架作为仅实现框架,您可以像下面那样做:

@_implementationOnly import ThirdPartyFrameworkName

最后一件事是,在您的代码中,您需要检查是否实际加载了此第三方框架,以便您的代码不会崩溃,以防有人不将此第三方框架添加到他的应用程序中。因此,您的框架中使用第三方框架的可选功能应首先检查,例如,在使用它之前是否存在此外部框架的给定 class,如下所示:

if NSClassFromString("ClassNameFromThirdPartyFramework") == nil {
    return // third party framework not available
}
// do something with ClassNameFromThirdPartyFramework here

如果您执行了所有这些步骤,它应该会起作用。