BLACK FRIDAY: Save 50% on all my Swift books and bundles! >>

Enum with Dictionary Values

Forums > SwiftUI

Why would you want to use Enum with dictionary values, because you get the benefit of the features of using an enum (closed, consistent and complete list) with the possibility of having associated values for any additional functionality (icons, labels, text, accessibility labels, etc.).

There maybe a better or different way to get the same effect, so consider

enum VolumeSetting: String, CaseIterable, Identifiable {
    case loud = "Loud"
    case normal = "Normal"
    case soft = "Soft"

    var id: String { self.rawValue }
}

func volumeValue(for volume: VolumeSetting) -> Float {
    // do not want to increase dictionary size either deliberately or by accident
    guard VolumeSetting.allCases.contains(volume) else { return 0.5 }

    let volumeValue: [VolumeSetting: Float] = [
        .loud: 0.75,
        .normal: 0.5,
        .soft: 0.25
    ]

    return volumeValue[volume]!
}

func volumeIcon (for volume: VolumeSetting) -> String {
    // do not want to increase dictionary size either deliberately or by accident
    guard VolumeSetting.allCases.contains(volume) else { return "speaker.wave.2" }

    let volumeIcon: [VolumeSetting: String] = [
        .loud: "speaker.wave.3",
        .normal: "speaker.wave.2",
        .soft: "speaker.wave.1"
    ]

    return volumeIcon[volume]!
}

Assuming that audioPlayer has already been created as an AVAudioPlayer type instance, you can write

audioPlayer?.setVolume(volumeValue(for: volumeSetting), fadeDuration: 3)

and 'volumeSetting' is defined as a VolumeSetting enum.

playAlarmSound(volumeSetting)

and

Button("\(Image(systemName: volumeIcon(for: volumeSetting)))") {
       // more code here
}
.accessibilityElement()
.accessibilityLabel("Volume")
.accessibilityHint("Volume is \(volumeSetting.rawValue.description)")

2      

Rather than have freestanding functions that provide that information and involve creating a Dictionary, you can just add computed properties to your enum. And you won't need a guard to make sure your function has been passed a valid VolumeSetting value, because the compiler will ensure that you can only have legit values.

enum VolumeSetting: String, CaseIterable, Identifiable {
    case loud = "Loud"
    case normal = "Normal"
    case soft = "Soft"

    var id: String { self.rawValue }

    var value: Float { 
    //although I might come up with a better name than this
        switch self {
            case .loud: return 0.75
            case .normal: return 0.5
            case .soft: return 0.25
        }
    }

    var icon: String {
        switch self {
            case .loud: return "speaker.wave.3"
            case .normal: return "speaker.wave.2"
            case .soft: return "speaker.wave.1"
        }
    }
}

And usage like so:

audioPlayer?.setVolume(volumeSetting.value, fadeDuration: 3)

and

playAlarmSound(volumeSetting)

and

Button("\(Image(systemName: volumeSetting.icon))") {
       // more code here
}
.accessibilityElement()
.accessibilityLabel("Volume")
.accessibilityHint("Volume is \(volumeSetting.rawValue)")
//don't need to use description here since the RawValue of your enum is a String

This is one of the great things about Swift enums, that they can have properties and methods and such. This way, everything is encapsulated right there in the enum itself.

5      

Save 50% in my WWDC sale.

SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.