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
}
}
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.
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.
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.
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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With