Objective-C 枚举值转换为 Swift 枚举
Objective-C enum value into Swift enum
在你对这个问题进行投票之前,我想知道我正在尝试做的事情是多么愚蠢。也许我还是没能正确理解枚举。
所以,我正在开发一个使用 Obj-C 框架的项目。此框架包含枚举:
typedef enum : NSInteger
{
kImageSizeUnknown = 0,
kImageSize75,
kImageSize110,
kImageSize170,
kImageSize220,
kImageSize300,
kImageSize450,
kImageSize720,
kImageSize1080,
/* Size aliases */
kImageSizeThumbnail = kImageSize75,
kImageSizeSmall = kImageSize170,
kImageSizeMedium = kImageSize450,
kImageSizeLarge = kImageSize720,
kImageSizeXLarge = kImageSize1080
} GnImageSize;
我希望能够以某种方式声明一个 Swift 枚举,其中 returns Obj-C 枚举的值(这可能是愚蠢的部分)。
我现在就是这样。
enum GNImageSize:Int, CaseIterable{
case thumbnail
case sizeSmall
func toGnImageSize() -> GnImageSize {
switch self {
case .thumbnail:
return kImageSizeThumbnail
case .sizeSmall:
return kImageSizeSmall
}
}
static func toGnImageSize(sizeType:GNImageSize) -> GnImageSize {
switch sizeType {
case .thumbnail:
return kImageSizeThumbnail
case .sizeSmall:
return kImageSizeSmall
}
}
}
然而当我这样做时:
enum GNImageSize:Int, CaseIterable{
case thumbnail = GnImageSize.kImageSizeThumbnail
case sizeSmall = GnImageSize.kImageSizeSmall
}
我收到以下错误消息:
Raw value for enum case must be a literal
谢谢。
编辑
与 Obj-c 函数通信的函数
func getArtworkURL(forImageType imageType:GNImageSize, shouldFindAlternatives:Bool, highQualityFirst:Bool)->URL?{
if let asset = coverArt()?.asset(GnImageSize(rawValue: imageType.rawValue)), let assetURL = asset.urlHttp(){
return URL(string:assetURL)
}
else{
if shouldFindAlternatives{
if highQualityFirst{
for size in GNImageSize.allCases.reversed(){
if let asset = coverArt()?.asset(GnImageSize(rawValue: size.rawValue)), let assetURL = asset.urlHttp(){
return URL(string:assetURL)
}
}
}
else{
for size in GNImageSize.allCases{
if let asset = coverArt()?.asset(GnImageSize(rawValue: size.rawValue)), let assetURL = asset.urlHttp(){
return URL(string:assetURL)
}
}
}
}
}
return nil
}
在哪里
-(nullable GnAsset*) asset: (GnImageSize)imageSize;
那个raw-value style enum grammar
错误。
raw-value-assignment → = raw-value-literal
raw-value-literal → numeric-literal | static-string-literal | boolean-literal
所以,只有数字(数字如 -7
、0x10
、0b010
)、静态字符串(引号中的字符,如 "foo"
)和布尔值(true
或 false
) 文字 是允许的。
其他任何方法都行不通。
五个 size 别名 具有(原始)值 1、3、6、7、8,因此声明一个 Swift 枚举
enum GNImageSize : Int {
case thumbnail = 1
case small = 3
case medium = 6
case large = 7
case xLarge = 8
}
要在 Swift 中使用 Int
值,例如使用
GNImageSize.thumbnail.rawValue
或者创建一个带有静态属性的自定义枚举来映射类型
enum GNImageSize {
static let thumbnail = GnImageSize(0)
static let small = GnImageSize(3)
static let medium = GnImageSize(6)
static let large = GnImageSize(7)
static let xLarge = GnImageSize(8)
}
我不明白 ObjC 框架在 2018 年仍然使用石器时代语法 typedef enum : NSInteger { ... } Foo;
而不是 Swift 兼容语法 typedef NS_ENUM (NSInteger, Foo) { ... };
后一种语法存在了 6 年(iOS6、macOS 10.8).
在你对这个问题进行投票之前,我想知道我正在尝试做的事情是多么愚蠢。也许我还是没能正确理解枚举。
所以,我正在开发一个使用 Obj-C 框架的项目。此框架包含枚举:
typedef enum : NSInteger
{
kImageSizeUnknown = 0,
kImageSize75,
kImageSize110,
kImageSize170,
kImageSize220,
kImageSize300,
kImageSize450,
kImageSize720,
kImageSize1080,
/* Size aliases */
kImageSizeThumbnail = kImageSize75,
kImageSizeSmall = kImageSize170,
kImageSizeMedium = kImageSize450,
kImageSizeLarge = kImageSize720,
kImageSizeXLarge = kImageSize1080
} GnImageSize;
我希望能够以某种方式声明一个 Swift 枚举,其中 returns Obj-C 枚举的值(这可能是愚蠢的部分)。
我现在就是这样。
enum GNImageSize:Int, CaseIterable{
case thumbnail
case sizeSmall
func toGnImageSize() -> GnImageSize {
switch self {
case .thumbnail:
return kImageSizeThumbnail
case .sizeSmall:
return kImageSizeSmall
}
}
static func toGnImageSize(sizeType:GNImageSize) -> GnImageSize {
switch sizeType {
case .thumbnail:
return kImageSizeThumbnail
case .sizeSmall:
return kImageSizeSmall
}
}
}
然而当我这样做时:
enum GNImageSize:Int, CaseIterable{
case thumbnail = GnImageSize.kImageSizeThumbnail
case sizeSmall = GnImageSize.kImageSizeSmall
}
我收到以下错误消息:
Raw value for enum case must be a literal
谢谢。
编辑 与 Obj-c 函数通信的函数
func getArtworkURL(forImageType imageType:GNImageSize, shouldFindAlternatives:Bool, highQualityFirst:Bool)->URL?{
if let asset = coverArt()?.asset(GnImageSize(rawValue: imageType.rawValue)), let assetURL = asset.urlHttp(){
return URL(string:assetURL)
}
else{
if shouldFindAlternatives{
if highQualityFirst{
for size in GNImageSize.allCases.reversed(){
if let asset = coverArt()?.asset(GnImageSize(rawValue: size.rawValue)), let assetURL = asset.urlHttp(){
return URL(string:assetURL)
}
}
}
else{
for size in GNImageSize.allCases{
if let asset = coverArt()?.asset(GnImageSize(rawValue: size.rawValue)), let assetURL = asset.urlHttp(){
return URL(string:assetURL)
}
}
}
}
}
return nil
}
在哪里
-(nullable GnAsset*) asset: (GnImageSize)imageSize;
那个raw-value style enum grammar
错误。
raw-value-assignment → = raw-value-literal
raw-value-literal → numeric-literal | static-string-literal | boolean-literal
所以,只有数字(数字如 -7
、0x10
、0b010
)、静态字符串(引号中的字符,如 "foo"
)和布尔值(true
或 false
) 文字 是允许的。
其他任何方法都行不通。
五个 size 别名 具有(原始)值 1、3、6、7、8,因此声明一个 Swift 枚举
enum GNImageSize : Int {
case thumbnail = 1
case small = 3
case medium = 6
case large = 7
case xLarge = 8
}
要在 Swift 中使用 Int
值,例如使用
GNImageSize.thumbnail.rawValue
或者创建一个带有静态属性的自定义枚举来映射类型
enum GNImageSize {
static let thumbnail = GnImageSize(0)
static let small = GnImageSize(3)
static let medium = GnImageSize(6)
static let large = GnImageSize(7)
static let xLarge = GnImageSize(8)
}
我不明白 ObjC 框架在 2018 年仍然使用石器时代语法 typedef enum : NSInteger { ... } Foo;
而不是 Swift 兼容语法 typedef NS_ENUM (NSInteger, Foo) { ... };
后一种语法存在了 6 年(iOS6、macOS 10.8).