How to Declare Enums in Swift of a Particular Class Type

How to declare enums in Swift of a particular class type?

From Docs

In particular, the raw-value type must conform to the Equatable
protocol and one of the following protocols:
ExpressibleByIntegerLiteral for integer literals,
ExpressibleByFloatLiteral for floating-point literals,
ExpressibleByStringLiteral for string literals that contain any number
of characters, and ExpressibleByUnicodeScalarLiteral or
ExpressibleByExtendedGraphemeClusterLiteral for string literals that
contain only a single character.

So make your class Abc to conform to Equatable and one of the above mentioned protocols. Here is an example

public class Abc : Equatable,ExpressibleByStringLiteral{
var age = 25
var name = "Abhi"
public static func == (lhs: Abc, rhs: Abc) -> Bool {
return (lhs.age == rhs.age && lhs.name == rhs.name)
}
public required init(stringLiteral value: String) {
let components = value.components(separatedBy: ",")
if components.count == 2 {
self.name = components[0]
if let age = Int(components[1]) {
self.age = age
}
}
}
public required convenience init(unicodeScalarLiteral value: String) {
self.init(stringLiteral: value)
}
public required convenience init(extendedGraphemeClusterLiteral value: String) {
self.init(stringLiteral: value)
}
}

enum TestEnum : Abc {
case firstCase = "Jack,29"
case secondCase = "Jill,26"
}

Now you can initialize your enum like

let exEnum = TestEnum.firstCase
print(exEnum.rawValue.name) // prints Jack

For detailed discussion and example you can refer
https://swiftwithsadiq.wordpress.com/2017/08/21/custom-types-as-raw-value-for-enum-in-swift/

How can I create enum from custom class in Swift

my solution 1 finding on network

enum Devices: CGSize {
case iPhone3GS = "{320, 480}"
case iPhone5 = "{320, 568}"
case iPhone6 = "{375, 667}"
case iPhone6Plus = "{414, 736}"
}

extension CGSize: StringLiteralConvertible {
public init(stringLiteral value: String) {
let size = CGSizeFromString(value)
self.init(width: size.width, height: size.height)
}

public init(extendedGraphemeClusterLiteral value: String) {
let size = CGSizeFromString(value)
self.init(width: size.width, height: size.height)
}

public init(unicodeScalarLiteral value: String) {
let size = CGSizeFromString(value)
self.init(width: size.width, height: size.height)
}
}

and my solution 2 from my mind (workaround), this not init from class/struct but its has my data

typealias MyTypeData = (title: String, iconName: String)
enum MyType: String {
case Test1
case Test2

private var data: MyTypeData {
switch self {
case .Test1: return (title: "One", iconName: "icn1")
case .Test2: return (title: "Two", iconName: "icn2")
}
}

var title: String { get { return data.title } }
var icon: UIImage? { get { return UIImage(named: data.iconName) } }

}

How to return and use an enum of Swift class types or methods

String Solution:

You may be able to use NSClassFromString to your advantage in this scenario. Consider the following example:

enum State: String {
case StartState = "StartClass"
case DownloadState = "DownloadClass"
case BaseState = "BaseClass"

var klass: AnyClass {
return NSClassFromString(self.rawValue)!
}
}

Let me know if this sort of solution is what you are looking for.

Alternative Solution:

If you want to not depend on typing the string solutions then you'll need to have a simple switch statement for the class types:

class StartClass {}
class DownloadClass {}
class BaseClass {}

enum State {
case StartState
case DownloadState
case BaseState

var klass: AnyClass {
switch self {
case .StartState:
return StartClass.self
case .DownloadState:
return DownloadClass.self
case .BaseState:
return BaseClass.self
}
}
}

Enum class in swift

Why don't you simply add a static property to your enum Type?

enum Type: Int {
case A = 0, B, C
static let all = [A, B, C]
}

Swift - Passing different enum types for same variable to a class

For applying abstraction, you could use protocol, as follows:

protocol Menu {}

enum Menu1: String, Menu {
case option1 = "Option 01 From Menu 01"
case option2 = "Option 02 From Menu 01"
case option3 = "Option 03 From Menu 01"
case option4 = "Option 04 From Menu 01"
case option5 = "Option 05 From Menu 01"
}

enum Menu2: String, Menu {
case option1 = "Option 01 From Menu 02"
case option2 = "Option 02 From Menu 02"
case option3 = "Option 03 From Menu 02"
case option4 = "Option 04 From Menu 02"
case option5 = "Option 05 From Menu 02"
}

By implementing this, you are able to declare arrays of Menu type, which include both of the enums:

let myMenu1Array: [Menu1] = [.option1, .option2, .option5]
let myMenu2Array: [Menu2] = [.option1, .option3, .option4]

For instance, a function that takes a parameter as array of Menus should work:

func handleMenu(_ menuArray: [Menu]) {
if let menu1Array = menuArray as? [Menu1] {
print("Menu 1 Detected!")

// you could iterate through it for instance...
for option in menu1Array {
print(option.rawValue)
}

return
}

if let menu2Array = menuArray as? [Menu2] {
print("Menu 2 Detected!")

// you could iterate through it for instance...
for option in menu2Array {
print(option.rawValue)
}

return
}
}

The output would be:

handleMenu(myMenu1Array)
/*
Menu 1 Detected!
Option 01 From Menu 01
Option 02 From Menu 01
Option 05 From Menu 01
*/

handleMenu(myMenu2Array)
/*
Menu 2 Detected!
Option 01 From Menu 02
Option 03 From Menu 02
Option 04 From Menu 02
*/

So, if you have a property in a class that should represents a menu, you could declare it as a type of Menu:

class  MyClass {
...

var menu: Menu?

...
}

How to enumerate an enum with String type?

Swift 4.2+

Starting with Swift 4.2 (with Xcode 10), just add protocol conformance to CaseIterable to benefit from allCases. To add this protocol conformance, you simply need to write somewhere:

extension Suit: CaseIterable {}

If the enum is your own, you may specify the conformance directly in the declaration:

enum Suit: String, CaseIterable { case spades = "♠"; case hearts = "♥"; case diamonds = "♦"; case clubs = "♣" }

Then the following code will print all possible values:

Suit.allCases.forEach {
print($0.rawValue)
}


Compatibility with earlier Swift versions (3.x and 4.x)

If you need to support Swift 3.x or 4.0, you may mimic the Swift 4.2 implementation by adding the following code:

#if !swift(>=4.2)
public protocol CaseIterable {
associatedtype AllCases: Collection where AllCases.Element == Self
static var allCases: AllCases { get }
}
extension CaseIterable where Self: Hashable {
static var allCases: [Self] {
return [Self](AnySequence { () -> AnyIterator<Self> in
var raw = 0
var first: Self?
return AnyIterator {
let current = withUnsafeBytes(of: &raw) { $0.load(as: Self.self) }
if raw == 0 {
first = current
} else if current == first {
return nil
}
raw += 1
return current
}
})
}
}
#endif

using enum to store current state class in swift

To answer your core question, you could use enums with associated values for better case handling.

Associated Values


...

You can define Swift enumerations to store associated values of any
given type, and the value types can be different for each case of the
enumeration if needed. Enumerations similar to these are known as
discriminated unions, tagged unions, or variants in other programming
languages.

Ref: Swift Documentation on Enums


Example:

enum State {
case state1(_ state: State1.Type)
case state2(_ state: State2.Type)
}

let currentState = State.state1(State1.self)

//Using switch for handling multiple cases
switch currentState {
case .state1(let state):
state.getInfo()
case .state2(let state):
state.getInfo()
}

//Using if for handling single cases
if case State.state1(let state) = currentState {
state.getInfo()
}

More on Enums with Associated Values here:

  • Swift Documentation on Enums(Read Sub-Topic: Associated Values)
  • Advanced and Practical Enum usage in Swift

Using enum declared in class in the protocol of the class itself in Swift?

To access types declared within another type (Nested Types), put surrounding type's name before nested type:

func iCloudFetched(recordType: iCloud.recordType)

For more information about Nested Types in Swift: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/NestedTypes.html



Related Topics



Leave a reply



Submit