Reimond Hill
Reimond Hill

Reputation: 4760

Objective-C enum value into Swift enum

Before you vote on this question I would like to how dumb what I am trying to do is. Maybe I still don't understand properly enums.

So, I am working on a project that uses an Obj-C framework. This framework contains enums:

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;

I want somehow be able to declare a Swift enum that returns values of the Obj-C enum (That might be the silly part).

That is how I have at the moment.

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
        }
    }

}

However when I do:

enum GNImageSize:Int, CaseIterable{
    case thumbnail = GnImageSize.kImageSizeThumbnail
    case sizeSmall = GnImageSize.kImageSizeSmall
}

I get the following error message:

Raw value for enum case must be a literal

Thank you.

EDIT Function that comunicates with Obj-c functions

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

}

Where

-(nullable GnAsset*) asset: (GnImageSize)imageSize;

Upvotes: 0

Views: 1995

Answers (2)

vadian
vadian

Reputation: 285250

The five size aliases have the (raw) values 1, 3, 6, 7, 8 so declare a Swift enum

enum GNImageSize : Int {
    case thumbnail = 1
    case small     = 3
    case medium    = 6
    case large     = 7
    case xLarge    = 8
}

To use the Int value in Swift use for example

GNImageSize.thumbnail.rawValue

Alternatively create a custom enum with static properties to map the types

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)
}

I don't understand that in 2018 ObjC frameworks still use the Stone-age syntax typedef enum : NSInteger { ... } Foo; rather than Swift compliant syntax typedef NS_ENUM (NSInteger, Foo) { ... }; The latter syntax exists for 6 years (iOS 6, macOS 10.8).

Upvotes: 2

user28434'mstep
user28434'mstep

Reputation: 6600

That raw-value style enum grammar error.

raw-value-assignment → = raw-value-literal

raw-value-literal → numeric-literal | static-string-literal | boolean-literal

So, only numeric(numbers like -7, 0x10, 0b010), static string(characters in quotes, like "foo") and boolean(true or false) literals are allowed there.

Anything else won't work.

Upvotes: 0

Related Questions