bog*_*gen 58 enums interop objective-c swift
我有这个带有String值的枚举,它将用于告诉API方法记录服务器消息具有什么样的服务器性.我正在使用Swift 1.2,因此枚举可以映射到Objective-C
@objc enum LogSeverity : String {
case Debug = "DEBUG"
case Info = "INFO"
case Warn = "WARN"
case Error = "ERROR"
}
Run Code Online (Sandbox Code Playgroud)
我收到了错误
@objc enum raw type String不是整数类型
我没有设法找到任何说只有整数可以从Swift转换为Objective-C的地方.是这样的吗?如果是这样,有没有人有任何关于如何在Objective-C中提供这样的东西的最佳实践建议?
Rem*_*lia 57
其中一个解决方案是使用RawRepresentable协议.
编写init和rawValue方法并不理想,但允许您像往常一样在Swift和Objective-C中使用此枚举.
@objc public enum LogSeverity: Int, RawRepresentable {
case debug
case info
case warn
case error
struct Constants {
static let routes: [LogSeverity: String] = [
.debug: "DEBUG",
.info: "INFO",
.warn: "WARN",
.error: "ERROR"
]
}
public typealias RawValue = String
public var rawValue: RawValue {
guard let value = Constants.routes[self] else {
fatalError("constants definition is missing: \(self)")
}
return value
}
public init?(rawValue: RawValue) {
guard let severity = Constants.routes.first(where: { $0.value == rawValue }) else {
return nil
}
self = severity.key
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*n R 49
从Xcode 6.3发行说明(重点补充):
快速语言增强功能
...
现在可以使用@objc属性将Swift枚举导出到Objective-C.@objc枚举必须声明整数原始类型,并且不能是通用的或使用关联的值.因为Objective-C枚举不是命名空间,所以枚举案例被导入到Objective-C中作为枚举名称和案例名称的串联.
Dav*_*vid 22
这是一个有效的解决方案.
@objc public enum ConnectivityStatus: Int {
case Wifi
case Mobile
case Ethernet
case Off
func name() -> String {
switch self {
case .Wifi: return "wifi"
case .Mobile: return "mobile"
case .Ethernet: return "ethernet"
case .Off: return "off"
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你真的想要实现这个目标,这就是解决方法.但是,您可以访问Objective C接受的对象中的枚举值,而不是实际的枚举值.
enum LogSeverity : String {
case Debug = "DEBUG"
case Info = "INFO"
case Warn = "WARN"
case Error = "ERROR"
private func string() -> String {
return self.rawValue
}
}
@objc
class LogSeverityBridge: NSObject {
class func Debug() -> NSString {
return LogSeverity.Debug.string()
}
class func Info() -> NSString {
return LogSeverity.Info.string()
}
class func Warn() -> NSString {
return LogSeverity.Warn.string()
}
class func Error() -> NSString {
return LogSeverity.Error.string()
}
}
Run Code Online (Sandbox Code Playgroud)
致电:
NSString *debugRawValue = [LogSeverityBridge Debug]
Run Code Online (Sandbox Code Playgroud)
Xcode 8 的代码,使用Int有效但其他方法未公开给 Objective-C的事实。这实在是太可怕了……
class EnumSupport : NSObject {
class func textFor(logSeverity severity: LogSeverity) -> String {
return severity.text()
}
}
@objc public enum LogSeverity: Int {
case Debug
case Info
case Warn
case Error
func text() -> String {
switch self {
case .Debug: return "debug"
case .Info: return "info"
case .Warn: return "warn"
case .Error: return "error"
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不介意在(Objective)C中定义值,则可以使用NS_TYPED_ENUM宏在Swift中导入常量。
例如:
.h文件
typedef NSString *const ProgrammingLanguage NS_TYPED_ENUM;
FOUNDATION_EXPORT ProgrammingLanguage ProgrammingLanguageSwift;
FOUNDATION_EXPORT ProgrammingLanguage ProgrammingLanguageObjectiveC;
Run Code Online (Sandbox Code Playgroud)
.m文件
ProgrammingLanguage ProgrammingLanguageSwift = "Swift";
ProgrammingLanguage ProgrammingLanguageObjectiveC = "ObjectiveC";
Run Code Online (Sandbox Code Playgroud)
在Swift中,它是这样导入的struct:
struct ProgrammingLanguage: RawRepresentable, Equatable, Hashable {
typealias RawValue = String
init(rawValue: RawValue)
var rawValue: RawValue { get }
static var swift: ProgrammingLanguage { get }
static var objectiveC: ProgrammingLanguage { get }
}
Run Code Online (Sandbox Code Playgroud)
尽管该类型未作为桥接enum,但在Swift代码中使用它时却感觉非常相似。
您可以在结合使用Swift和Cocoa和Objective-C文档的“与C API交互”中阅读有关此技术的更多信息。
| 归档时间: |
|
| 查看次数: |
37746 次 |
| 最近记录: |