I'm trying to save the user choice from picker component in UserDefault in SwiftUI but in contrary of a simple toggle, I'am blocked.
My View:
import SwiftUI
enum VibrationType: String, CaseIterable {
case low = "Faible"
case normal = "Normal"
case hight = "Fort"
}
struct CompassSettings: View {
@ObservedObject var settingsStore: SettingsStore = SettingsStore()
@State var vibrationIntensityIndex = 1
var body: some View {
VStack {
Toggle(isOn: $settingsStore.vibrationActivate) {
Text("Activer la vibration")
.font(.system(size: 18))
.foregroundColor(Color("TextDark"))
}
.padding(.top, 6)
Picker("Intesité de la vibration", selection: self.$settingsStore.vibrationIntensity) {
ForEach(0..<self.vibrationIntensity.count) { intensity in
Text(self.vibrationIntensity[intensity]).tag(intensity)
}
}
.pickerStyle(SegmentedPickerStyle())
}
}
}
SettingsStore class:
import SwiftUI
import Combine
final class SettingsStore: ObservableObject {
let vibrationIsActivate = PassthroughSubject<Void, Never>()
let intensityOfVibration = PassthroughSubject<Void, Never>()
// Vibration
var vibrationActivate: Bool = UserDefaults.vibrationActivated {
willSet {
UserDefaults.vibrationActivated = newValue
vibrationIsActivate.send()
}
}
// Vibration intensity
var vibrationIntensity: VibrationType = .normal {
willSet {
UserDefaults.vibrationIntensity = newValue
print(UserDefaults.vibrationIntensity)
intensityOfVibration.send()
}
}
}
The UserDefault extension:
extension UserDefaults {
private struct Keys {
static let vibrationActivated = "vibrationActivated"
static let vibrationIntensity = "vibrationIntensity"
}
// Vibration
static var vibrationActivated: Bool {
get { return UserDefaults.standard.bool(forKey: Keys.vibrationActivated) }
set { UserDefaults.standard.set(newValue, forKey: Keys.vibrationActivated) }
}
// Vibration intensity
static var vibrationIntensity: VibrationType {
get { return UserDefaults.standard.object(forKey: Keys.vibrationIntensity) as!
VibrationType ?? "normal" }
set { UserDefaults.standard.set(newValue, forKey: Keys.vibrationIntensity) }
}
}
So I have some errors in my UserDefaults extension. I don't know how I can save multiple string choices and how I can display a default choice.
Find below fixed code... tested with Xcode 11.2 / iOS 13.2.
enum VibrationType: String, CaseIterable {
case low = "Faible"
case normal = "Normal"
case hight = "Fort"
}
struct CompassSettings: View {
@ObservedObject var settingsStore: SettingsStore = SettingsStore()
@State var vibrationIntensityIndex = 1
@State var vibrationIntensity: [VibrationType] = [.low, .normal, .hight]
var body: some View {
VStack {
Toggle(isOn: $settingsStore.vibrationActivate) {
Text("Activer la vibration")
.font(.system(size: 18))
.foregroundColor(Color("TextDark"))
}
.padding(.top, 6)
Picker("Intesité de la vibration", selection: self.$settingsStore.vibrationIntensity) {
ForEach(self.vibrationIntensity, id: \.self) { intensity in
Text(intensity.rawValue).tag(intensity)
}
}
.pickerStyle(SegmentedPickerStyle())
}
}
}
final class SettingsStore: ObservableObject {
let vibrationIsActivate = PassthroughSubject<Void, Never>()
let intensityOfVibration = PassthroughSubject<Void, Never>()
// Vibration
var vibrationActivate: Bool = UserDefaults.vibrationActivated {
willSet {
UserDefaults.vibrationActivated = newValue
vibrationIsActivate.send()
}
}
// Vibration intensity
var vibrationIntensity: VibrationType = UserDefaults.vibrationIntensity {
willSet {
UserDefaults.vibrationIntensity = newValue
print(UserDefaults.vibrationIntensity)
intensityOfVibration.send()
}
}
}
extension UserDefaults {
private struct Keys {
static let vibrationActivated = "vibrationActivated"
static let vibrationIntensity = "vibrationIntensity"
}
// Vibration
static var vibrationActivated: Bool {
get { return UserDefaults.standard.bool(forKey: Keys.vibrationActivated) }
set { UserDefaults.standard.set(newValue, forKey: Keys.vibrationActivated) }
}
// Vibration intensity
static var vibrationIntensity: VibrationType {
get {
if let value = UserDefaults.standard.object(forKey: Keys.vibrationIntensity) as? String {
return VibrationType(rawValue: value)!
}
else {
return .normal
}
}
set {
UserDefaults.standard.set(newValue.rawValue, forKey: Keys.vibrationIntensity)
}
}
}