Xcode 11 中 Swift Combine.framework 的可选链接

Posted

技术标签:

【中文标题】Xcode 11 中 Swift Combine.framework 的可选链接【英文标题】:Optional linking for Swift Combine.framework in Xcode 11 【发布时间】:2019-12-01 18:45:56 【问题描述】:

我们的应用程序支持 ios 11 及更高版本。在 iOS 13 中,我们使用 SwiftUI + Combine

我们将SwiftUICombine 框架的导入与对应检查#if canImport(SwiftUI)#if canImport(Combine) 包装在一起。如果我们在 iOS 12 下从 Xcode 11 运行我们的应用程序,则会出现错误 dyld: Library not loaded: /System/Library/Frameworks/Combine.framework/Combine

我们通过可选链接解决了 SwiftUI 的相同问题。

但我们不能为组合做同样的事情,因为它甚至不能被选择用于链接

【问题讨论】:

既然我们说的是非常beta,也许你可以简单地改变它来寻找iOS 13?我很确定 - 不是 100% - both SwiftUI Combine** require not only the OS versions coming this fall but also Swift 5.1`。检查操作系统版本现在应该可以工作了。如果不?提交错误报告。 它在具有相同构建设置的 iOS 13 上完美运行。这里的Combine.framework 甚至不能从列表中选择的问题不能标记为可选。将为此准备小型演示项目 我明白了。 (对我来说)感觉最简单的方法是在你的应用程序中创建一个 iOS 13 分支。当然不理想,但您已经看到了采用其他任何方式的头痛。 【参考方案1】:

就我们今天发现的情况而言,如果您至少使用 Xcode 11.3.1 进行构建,则无需采用任何解决方法。即使在任何链接相关的配置/构建阶段等中没有提及 SwiftUI 或组合,它也可以开箱即用。

原来是(至少)Xcode-11.1 中的一个错误,导致默认情况下组合框架没有弱链接。看起来该错误至少在 Xcode-11.3.1 中已修复 - 默认情况下它确实弱链接了 Combine。苹果人的一些相关报告和回答在这里:https://forums.swift.org/t/why-swift-package-manager-does-not-support-weak-linking-weak-framework-swiftui/31418/2

【讨论】:

【参考方案2】:
    导航到目标设置的 Build Phases 选项卡,展开 Link binaries with libraries 部分并右键单击 SwiftUI.framework,然后选择在 Finder 中显示。 将 Combine.framework 从 Finder 窗口拖放到框架列表中,然后从状态弹出窗口中选择 Optional。 在项目浏览器(右侧窗口窗格)中选择 Combine.framework 项,然后从 Location 弹出窗口中选择 Relative to SDK检查员(左窗格)。 如果您得到一个奇怪的相对路径(以../iPhoneOS.sdk/ 开头),请在文本编辑器中打开项目并手动修复它。

【讨论】:

不错!第 4 步意味着编辑System/Library/Frameworks/Combine.framework的路径【参考方案3】:

当它在构建设置中可用时,您可以显式添加链接器标志以选择性地链接组合。 在 Xcode Build Settings 中添加 -weak_framework CombineOther Linker Flags

或在您的 XCConfig 文件中添加以下行:

OTHER_LDFLAGS = -weak_framework Combine

或者如果您仍想支持使用旧 Xcode 版本进行构建:

OTHER_LDFLAGS[sdk=iphoneos13.0] = -weak_framework Combine
OTHER_LDFLAGS[sdk=iphonesimulator13.0] = -weak_framework Combine

OTHER_LDFLAGS[sdk=watchos6.0] = -weak_framework Combine
OTHER_LDFLAGS[sdk=watchsimulator6.0] = -weak_framework Combine

OTHER_LDFLAGS[sdk=appletvos13.0] = -weak_framework Combine
OTHER_LDFLAGS[sdk=appletvsimulator13.0] = -weak_framework Combine

OTHER_LDFLAGS[sdk=macosx10.15] = -weak_framework Combine

【讨论】:

【参考方案4】:

受@nschmidt 回答的启发,但解决方案适用于 Xcode 10 和 Xcode 11

将此添加到 xcconfig

 OTHER_LDFLAGS_XCODE_SPECIFIC_1100 = -weak_framework Combine -weak_framework SwiftUI

 OTHER_LDFLAGS = $(inherited) $OTHER_LDFLAGS_XCODE_SPECIFIC_$(XCODE_VERSION_ACTUAL)

或添加 OTHER_LDFLAGS_XCODE_SPECIFIC_1100 作为自定义构建设置

【讨论】:

以上是关于Xcode 11 中 Swift Combine.framework 的可选链接的主要内容,如果未能解决你的问题,请参考以下文章

Swift Combine:没有“distinct”运算符?

Swift Combine - @Published 属性数组

升级到xcode 11.3后,Combine的接收器不起作用

SwiftUI 简明教程之 Swift Package Manager 的使用

Swift Combine:如何从发布者列表中创建单个发布者?

SwiftUI 简明教程之使用 UIKit