Reputation: 57
I'm now trying to learn about global variables that can be used across many different parts of an app.
I'm trying to create a global variable "Quarters" that can be used in any part of my app and that will save whatever the current value is even after the app is closed/quit.
My code below is not increasing my "quarters" variable. It just stays at 0. There are no errors either. I can get it to work if I have the variable inside the struct ContentView, but not if I try to make it a global variable.
import SwiftUI
struct MyVariables {
var quarters:Int = 0
}
struct ContentView: View {
//@State private var quarters = 0 - if I point to the variable this way, it works
var body: some View {
VStack {
Text("\(MyVariables.quarters)").bold()
Button(action: {
MyVariables.quarters += 1
}) {
Image("QuarterMachine")
}
}
}
}
I believe the below two codes can be used to save the variable, but I'm not certain since I can't figure out the above part first.
import Foundation
protocol Storage {
var quarters: Int { get }
func save(quarters: Int)
}
And also
import Foundation
class LocalStorage: Storage {
private let quartersKey = "quarters"
func reset() {
save(quarters: 0)
}
var quarters: Int {
UserDefaults().integer(forKey: quartersKey)
}
func save(quarters: Int) {
UserDefaults().set(quarters, forKey: quartersKey)
}
}
Upvotes: 1
Views: 141
Reputation: 3488
To save a value across all SwiftUI views and save it the same way UserDefaults would do, you can use @AppStorage
. Just use the same key, "quarters"
in this example, in the other views to retrieve the saved value.
As for answering your concern on how to update your value elsewhere that on the button tap, you can use a view model to handle all your logic and use @AppStorage
out of your view.
struct ContentView: View {
@StateObject var viewModel = GameViewModel()
var body: some View {
VStack {
Text("\(viewModel.quarters)")
.bold()
Button(action: { viewModel.quarters += 1 }) {
Image("QuarterMachine")
}
}
}
}
This is the view model to handle your logic.
final class GameViewModel: ObservableObject {
@AppStorage("quarters")
var quarters: Int = .zero
// You can use this method in your code to increase
// your quarters value when your game is finished.
func finishGame() {
quarters += 1
}
}
Upvotes: 1