当最低部署目标设置为iOS 12.2时,如何有条件地使用Combine @Published?

时间:2020-07-31 10:44:31

标签: ios swift combine

我有一个最低部署目标为 iOS 12.0 的应用。 SwiftUICombine中有部分内容。使用这两个库的所有方法和类型都标记为@available(iOS 13.0, *)。自1月份以来,该应用一直在这种混合设置下运行。

要利用ABI稳定性并减小应用程序大小,我想将新的最低部署目标设置为 iOS 12.2

当我这样做时,该应用程序在启动时崩溃(iOS 12.4模拟器),并且在控制台上显示了以下内容:

dyld:懒惰的符号绑定失败:无法解析符号 /Users/YYYYYYYYY/Library/Developer/CoreSimulator/Devices/UUD-UUD-UUD-UUD/data/Containers/Bundle/Application/UUD/XXXXXXX.app/XXXXXXX中的 _ $ s7Combine9PublishedVMa 因为无法加载依赖的dylib#29 dyld:无法解析 符号 _ $ s7Combine9PublishedVMa /用户/ YYYYYYYYY /库/开发人员/ CoreSimulator /设备/ UUD-UUD-UUD-UUD /数据/容器/捆绑/应用程序/ UUD-UUD-UUD-UUD / XXXXXXXapp / XXXXXXX 因为无法加载依赖的dylib#29

当尝试在运行iOS 12.4的iPhone上启动时,该应用程序也崩溃。

如果我从代码中删除了所有@Published,但保留了其他所有CombineSwiftUI相关的位,则该应用可以在iOS 12上使用。

即使所有包含@Published的类都标有@available(iOS 13.0, *),我也尝试将它们另外包装在#if canImport(Combine)中或将#if canImport(Combine)应用于每个@Published变量。这无济于事。

我知道我可以改变

@Published var name = ""

var name = "" {
    willSet {
        objectWillChange.send()
    }
}

但这似乎是一个令人讨厌的解决方法。

当设备运行 iOS 13.0 或更高版本时,如何将部署目标提高到 iOS 12.2 ,并继续使用@Published

2 个答案:

答案 0 :(得分:2)

您需要将Combine(如果也使用SwiftUI)框架与项目进行弱链接。您可以使用OTHER_LDFLAGS构建设置来实现。

OTHER_LDFLAGS = -weak_framework Combine -weak_framework SwiftUI

您实际上不需要canImport语句,只需要框架进行弱链接。当然,对于使用@available的所有类型,您仍然需要Combine注释。

答案 1 :(得分:1)

您不能在低于iOS 13的部署目标中使用属性包装器@Published。唯一的方法是如上所述。

在您的班级(应符合ObservableObject协议)中,而不是:

@Published var name = ""

您必须:

var name = "" {
    willSet {
        if #available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *) {
            self.objectWillChange.send()
        }
    }
}

您可能还需要在类中显式添加objectWillChange声明:

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public lazy var objectWillChange = ObservableObjectPublisher()