我有一个最低部署目标为 iOS 12.0 的应用。 SwiftUI
和Combine
中有部分内容。使用这两个库的所有方法和类型都标记为@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
,但保留了其他所有Combine
和SwiftUI
相关的位,则该应用可以在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
?
答案 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()