如何解决仅针对 Objective-C 导出 Swift var
我的 Swift 库 API 有一个 enum
类型的公共属性:
public enum Animal : String,Codable {
case Dog
case Cat
}
public var pet: Animal
enum
未导出为 @objc
,但我需要从 Objective-C 访问此属性。所以,我添加了一个计算属性
@objc public var petAsstring: String {
get { return String(reflecting: pet) }
set { pet = newValue == "Cat" ? Animal.Cat : Animal.Dog }
}
我可以对我的库的 Swift 使用者隐藏这个属性吗?或者,也许有更好的方法让它从 Objective-C 中使用,而没有丑陋的“Asstring”后缀?
更新:很抱歉歪曲了我的根本问题。我选择经历所有这些麻烦,因为当时我不明白 Swift typealias
允许我将长而丑陋但明确的 enum AlexPetLib_Animal
导出到 Objective-C,而我和第三方的所有 Swift 代码仍然可以使用正确命名的 Animal
别名:
public typealias Animal = AlexPetLib_Animal
@objc public enum AlexPetLib_Animal : Int,Codable {
case Dog
case Cat
}
我的库代码不需要额外的更改;使用该库的 Swift 应用程序只需重新编译即可。
解决方法
具有完整原始值类型的枚举可以是 @objc
,因此您可以使用 Int
作为 Animal
的原始值类型:
@objc
public enum Animal : Int,Codable {
case dog
case cat
}
要在 Swift 中复制 String
原始值类型的行为,请添加以下成员:
var stringValue: String {
switch self {
case .cat: return "Cat"
case .dog: return "Dog"
}
}
init?(stringValue: String) {
switch stringValue {
case "Cat": self = .cat
case "Dog": self = .dog
default: return nil
}
}
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let string = try container.decode(String.self)
if let animal = Animal(stringValue: string) {
self = animal
} else {
throw DecodingError.dataCorruptedError(in: container,debugDescription: "Expected cat or dog!")
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(stringValue)
}
与“使用 Animal
方法为每个事物编写两个版本”不同,这四个成员是您唯一需要的额外内容。之后,您将能够将使用 Animal
的所有内容标记为 @objc
(当然前提是它不使用其他非 @objc
内容)。
边缘情况是将 Animal
传递给接受通用 RawRepresentable
的方法时,它将使用 Int
原始值,但我不经常发生这种情况...
总结:没有任何技巧可以对 Swift 消费者隐藏 Swift var 或 func,但也有可能不会只是为了对 Obj-C 消费者隐藏它,而且还使用 @objc(AnotherName)
模式以不同的名称向他们公开。
对于我的特定用例,这允许我以库前缀的名称将 enum 公开给 Obj-C,与使用不受保护的基于字符串的 API 相比,这绝对是一个更好的选择。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。