I want to return an enum
from my function. For that, I need to classify a return type.
However, what is the return type if I want to return an enum
?
My code below:
class Timezone {
func getTimeZoneFromCountry(country: String) -> ??? {
switch country {
case "AU":
return Timezone.AU
case "US":
return Timezone.US
default:
return Timezone.AU
}
}
enum AU: String, Identifiable, CaseIterable {
case AEST = "AEST"
case AWST = "AWST"
case ACST = "ACST"
var id: AU {self}
}
enum US: String, Identifiable, CaseIterable {
case CST = "CST"
case EST = "EST"
case MST = "MST"
case PST = "PST"
var id: US {self}
}
}
I'm trying to dynamically populate a Picker
:
struct TimeZonePicker: View {
@Binding var country: String // AU or US
var body: some View {
Picker("Timezone", selection: $country) {
ForEach(*Dynamic enum here*) { i in
Text(String(i.rawValue))
}
}
}
}
Edit: New view with @Sweeper's dynamic solution:
var body: some View {
Picker("Timezone", selection: $country) {
ForEach(Timezone.getTimeZoneFromCountry(country: country)) { i in
Text(String(i.rawValue))
}
}
}
Use a single enum, and have getTimeZoneFromCountry
return only certain cases of the enum:
enum Timezone: String, Identifiable, CaseIterable {
var id: Timezone { self }
static func getTimeZoneFromCountry(country: String) -> [Timezone] {
switch country {
case "AU":
return Timezone.AU
case "US":
return Timezone.US
default:
return Timezone.AU
}
}
case AEST = "AEST"
case AWST = "AWST"
case ACST = "ACST"
case CST = "CST"
case EST = "EST"
case MST = "MST"
case PST = "PST"
static let AU: [Timezone] = [.AEST, .AWST, .ACST]
static let US: [Timezone] = [.CST, .EST, .MST, .PST]
}
The accepted answer is a good fit but for those who are care about the quality of the code, these are extra:
You don't need to define the raw value for String
based enum
s when the raw value and the case is exactly the same! So
case AEST = "AEST"
is exactly equal to:
case AEST
You can extend the Identifiable
itself to have an implementation to all RawRepresentable
s:
extension Identifiable where Self: RawRepresentable {
var id: Self { self }
}
You can use associated value in the enum for sectioning values like:
enum Timezone {
case au([AU])
case us([US])
,,,
}
Try to avoid unknown behaviors by avoiding default assigning. You can have an optional init instead:
init?(raw: String) {
switch raw.lowercased() {
case "au": self = .au(AU.allCases)
case "us": self = .us(US.allCases)
default: return nil
}
}
Don't forget that strings are case sensitive! Try handle the sensitivity. for example check for lowercased
.
enum Timezone {
init?(raw: String) {
switch raw.lowercased() {
case "au": self = .au(AU.allCases)
case "us": self = .us(US.allCases)
default: return nil
}
}
case au([AU])
case us([US])
enum AU: String, Identifiable, CaseIterable {
case AEST
case AWST
case ACST
}
enum US: String, Identifiable, CaseIterable {
case CST
case EST
case MST
case PST
}
}
extension Identifiable where Self: RawRepresentable {
var id: Self { self }
}
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