微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

仅针对 Objective-C 导出 Swift var

如何解决仅针对 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 varfunc,但也有可能不会只是为了对 Obj-C 消费者隐藏它,而且还使用 @objc(AnotherName) 模式以不同的名称向他们公开。

对于我的特定用例,这允许我以库前缀的名称将 enum 公开给 Obj-C,与使用不受保护的基于字符串的 API 相比,这绝对是一个更好的选择。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。