Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enum of structs in Swift 3.0

I am trying to create an enum of a struct that I would like to initialize:

struct CustomStruct {
    var variable1: String
    var variable2: AnyClass
    var variable3: Int

    init (variable1: String, variable2: AnyClass, variable3: Int) {
        self.variable1 = variable1
        self.variable2 = variable2
        self.variable3 = variable3
    }
}

enum AllStructs: CustomStruct {
    case getData
    case addNewData

    func getAPI() -> CustomStruct {
        switch self {
            case getData:
                return CustomStruct(variable1:"data1", variable2: SomeObject.class, variable3: POST)

            case addNewData:
                // Same to same

            default:
                return nil
        }
    }
}

I get the following errors:

Type AllStructs does not conform to protocol 'RawRepresentable'

I am assuming that enums cannot be used this way. We must use primitives.

like image 787
Siddharth Avatar asked Jan 29 '17 14:01

Siddharth


People also ask

Is enum a struct Swift?

Coming from an objective c background, the difference between components like enums, classes, and structs was quite obvious for me: An Enum is a set of named values, Struct is structured data type, and of course Class allows us to create objects with all POO related stuff.

What does enum do in Swift?

Enumerations (or enums for short) in Swift define a common type for a group of related values. According to the Swift documentation, enums enable you to work with those values in a type-safe way within your code. Enums come in particularly handy when you have a lot of different options you want to encode.

What is the difference between struct vs enum?

A struct can contain both data variables and methods. Enum can only contain data types. A struct supports a private but not protected access specifier. Enum does not have private and protected access specifier.

Can we define type methods in classes structures and enums?

Classes, structures, and enumerations can all define instance methods, which encapsulate specific tasks and functionality for working with an instance of a given type. Classes, structures, and enumerations can also define type methods, which are associated with the type itself.


Video Answer


2 Answers

It should be:

struct CustomStruct {
    var apiUrl: String
    var responseType: AnyObject
    var httpType: Int

    init (variable1: String, variable2: AnyObject, variable3: Int) {
        self.apiUrl = variable1
        self.responseType = variable2
        self.httpType = variable3
    }
}

enum MyEnum {
    case getData
    case addNewData

    func getAPI() -> CustomStruct {
        switch self {
        case .getData:
            return CustomStruct(variable1: "URL_TO_GET_DATA", variable2: 11 as AnyObject, variable3: 101)
        case .addNewData:
            return CustomStruct(variable1: "URL_TO_ADD_NEW_DATA", variable2: 12 as AnyObject, variable3: 102)
        }
    }
}

Usage:

let data = MyEnum.getData
let myObject = data.getAPI()

// this should logs: "URL_TO_GET_DATA 11 101"
print(myObject.apiUrl, myObject.responseType, myObject.httpType)

Note that upon Naming Conventions, struct should named as CustomStruct and enum named as MyEnum.

In fact, I'm not pretty sure of the need of letting CustomStruct to be the parent of MyEnum to achieve what are you trying to; As mentioned above in the snippets, you can return an instance of the struct based on what is the value of the referred enum.

like image 126
Ahmad F Avatar answered Sep 30 '22 11:09

Ahmad F


I'm not commenting on the choice to use an enum here, but just explaining why you got that error and how to declare an enum that has a custom object as parent.

The error shows you the problem, CustomStruct must implement RawRepresentable to be used as base class of that enum.

Here is a simplified example that shows you what you need to do:

struct CustomStruct : ExpressibleByIntegerLiteral, Equatable {
    var rawValue: Int = 0

    init(integerLiteral value: Int){
        self.rawValue = value
    }

    static func == (lhs: CustomStruct, rhs: CustomStruct) -> Bool {
        return
            lhs.rawValue == rhs.rawValue
    }
}


enum AllStructs: CustomStruct {
    case ONE = 1
    case TWO = 2
}

A few important things that we can see in this snippet:

  1. The cases like ONE and TWO must be representable with a Swift literal, check this Swift 2 post for a list of available literals (int,string,array,dictionary,etc...). But please note that in Swift 3, the LiteralConvertible protocols are now called ExpressibleByXLiteral after the Big Swift Rename.
  2. The requirement to implement RawRepresentable is covered implementing one of the Expressible protocols (init?(rawValue:) will leverage the initializer we wrote to support literals).
  3. Enums must also be Equatable , so you'll have to implement the equality operator for your CustomStruct base type.
like image 20
uraimo Avatar answered Sep 30 '22 11:09

uraimo