Reputation: 1451
I would like to store the User's selection of the current language to UserDefaults. The user choose the language they prefer through a picker. Yet, I have no idea on how to place the code to update the UserDefaults.
Here is my code:
enum Language: Int, CaseIterable, Identifiable {
case en
case zh_hant
var description: String {
switch self {
case.en:
return "English"
case.zh_hant:
return "繁體中文"
}
}
var id: Int {
self.rawValue
}
}
And then in my model class:
final class ModelData: ObservableObject {
// this is to be used as the default when the app is first launch.
// However, if the user choose the language, the default should be retrieve from UserDefaults
@Published var currentLanguage: Language = Language.en
}
And the user interface for selecting language:
struct ConfigurationView: View {
@EnvironmentObject var modelData: ModelData
let lang_title = ["Language", "語言"]
var body: some View {
List {
VStack {
HStack {
Text(lang_title[modelData.currentLanguage.rawValue]).font(.title2)
Spacer()
}
Picker("Language", selection: $modelData.currentLanguage) {
ForEach(Language.allCases, id: \.id) { language in
Text(language.description).tag(language)
}
}
.pickerStyle(SegmentedPickerStyle())
}
.padding()
}
}
}
How can I load the selected language from UserDefaults and update if the user selected?
Upvotes: 1
Views: 442
Reputation: 168
I would simple do:
import SwiftUI
final class ModelData: ObservableObject {
// this is to be used as the default when the app is first launch.
// However, if the user choose the language, the default should be retrieve from UserDefaults
@AppStorage("currentLanguage") var currentLanguage: Language = Language.en
}
Upvotes: 1
Reputation: 257573
Here is a possible way (the value to store/restore you can chose as you want)
Picker("Language", selection: $modelData.currentLanguage) {
ForEach(Language.allCases, id: \.id) { language in
Text(language.description).tag(language)
}
}
.pickerStyle(SegmentedPickerStyle())
.onChange(of: modelData.currentLanguage) {
UserDefaults.standard.setValue($0.rawValue, forKey: "language")
}
and creation (or in init
if needed some decoding)
final class ModelData: ObservableObject {
@Published var currentLanguage = Language(rawValue: UserDefaults.standard.value(forKey: "language") as? Int ?? 0)!
}
Also as alternate you can consider AppStorage
property wrapper inside ConfigurationView
view.
Upvotes: 2