Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to require an enum be defined in Swift Protocol

Is it possible to have a Protocol require that an enum be defined?

//trying to do this
protocol JSONEncodable {
    enum PropertyName // Type not allowed here
    func valueForProperty(propertyName:PropertyName) -> Any
}

//which would be implemented like this
struct Person : JSONEncodable {
    var firstName : String
    var lastName : String

    enum PropertyName {
        case FirstName
        case LastName
        func allValues() {
            return [Person.PropertyName.FirstName, Person.PropertyName.LastName]
        }
        func stringValue() {
            return "\(self)"
        }
    }
    func valueForProperty(propertyName:PropertyName) -> Any {
        switch propertyName {

        case .FirstName:
            return firstName

        case .LastName:
            return lastName
        }
    }
}

//so that I could do something like this
extension JSONEncodable {

    func JSONObject() -> [String:AnyObject] {
        var dictionary = [String:AnyObject]()
        for propertyName in PropertyName.allValues {
            let value = valueForProperty(propertyName)

            if let valueObject = value as? AnyObject {
                dictionary[propertyName.stringValue()] = valueObject

            }else if let valueObject = value as? JSONEncodable {
                dictionary[propertyName.stringValue()] = valueObject.JSONObject()
            }

        }
        return dictionary
    }
}
like image 251
joels Avatar asked May 20 '16 18:05

joels


People also ask

Can enum conform to Swift protocol?

Yes, enums can conform protocols. You can use Swift's own protocols or custom protocols. By using protocols with Enums you can add more capabilities.

How do I enum in Swift?

In Swift, we can also assign values to each enum case. For example, enum Size : Int { case small = 10 case medium = 12 ... } Here, we have assigned values 29 and 31 to enum cases small and medium respectively.

Can we define method in enum Swift?

Swift enum syntax To define an enum in Swift, use the keyword enum followed by the name of the enum. The name of an enum in Swift should follow the PascalCase naming convention in which the first letter of each word in a compound word is capitalized.

Can a Swift enum have functions?

Cases as functions Finally, let's take a look at how enum cases relate to functions, and how Swift 5.3 brings a new feature that lets us combine protocols with enums in brand new ways. A really interesting aspect of enum cases with associated values is that they can actually be used directly as functions.


2 Answers

Protocols can have associatedtypes which would just need to be adhered to in any subclass:

enum MyEnum: String {     case foo     case bar }  protocol RequiresEnum {     associatedtype SomeEnumType: RawRepresentable where SomeEnumType.RawValue: StringProtocol      func doSomethingWithEnum(someEnumType: SomeEnumType) }  class MyRequiresEnum: RequiresEnum {     typealias SomeEnumType = MyEnum      func doSomethingWithEnum(someEnumType: SomeEnumType) {         switch someEnumType {         case .foo:             print("foo")         case .bar:             print("bar")         }     } }  let mre = MyRequiresEnum() mre.doSomethingWithEnum(.bar) 

Edit: The associatedtype must be adhered to

like image 196
Mackarous Avatar answered Sep 23 '22 20:09

Mackarous


I think you can do it with an associatedtype that adheres to RawRepresentable

Here's an example:

protocol SomeProtocol {     associatedtype SomeType: RawRepresentable } 

If you need to specify the type of RawRepresentable like String for example, you can do that:

protocol SomeProtocol {     associatedtype SomeType: RawRepresentable where SomeType.RawValue: StringProtocol } 

Now you'll have a compiler error if you try to implement the protocol with anything else than an enum that has String as RawRepresentable. I hope it helps.

like image 38
Robin Dorpe Avatar answered Sep 23 '22 20:09

Robin Dorpe