What is wrong with Swift's data persistence?

2 weeks ago 23
ARTICLE AD BOX

I'm having problems with SwiftData. For some reason, when I insert a model into the context in one view, it seems to work, but when querying the model context in another view, it shows as empty, and that's because the continue button that's supposed to show up when the model is saved isn't rendering. There doesn't seem to be any syntax bugs, and the other stuff seems to be working fine, so I don't know what I did wrong.

struct ContentView: View { @State var selectedTab: Tabs = .home @State var gameIsInSession: Bool = false @State var difficulty: Difficulties = .none @State var isGameContinued: Bool = false var body: some View { ZStack { switch selectedTab { case .home: if (gameIsInSession == false) { HomeTab(difficulty: $difficulty, gameIsInSession: $gameIsInSession, isGameContinued: $isGameContinued) } if (gameIsInSession == true && difficulty != .none) { GameBoard(isGameContinued: $isGameContinued, difficulty: $difficulty, gameIsInSession: $gameIsInSession) } case .stats: StatsTab() case .settings: SettingsTab() case .profile: ProfileTab() } } .frame(maxWidth: .infinity, maxHeight: .infinity) .overlay(alignment: .bottom) { TabBar(selectedTab: $selectedTab, gameIsInSession: $gameIsInSession) } } } struct HomeTab: View { @Query(sort: \ContinueGameData.lastUpdated) private var savedGame: [ContinueGameData] @State private var goToNext = false @Binding var difficulty: Difficulties @Binding var gameIsInSession: Bool @Binding var isGameContinued: Bool var body: some View { VStack { NavigationStack { Button { goToNext = true } label: { ZStack { Rectangle() .fill(Color(red: 0.0, green: 0.7, blue: 1.0)) .frame(width: 300.0, height: 80.0) .cornerRadius(5.0) .padding(0.0) Text("Play") .foregroundStyle(Color(red: 0.0, green: 0.0, blue: 0.0)) .font(.largeTitle) } .navigationDestination(isPresented: $goToNext) { DifficultySelectionPage(difficulty: $difficulty, gameIsInSession: $gameIsInSession) } } .padding(0.0) if (savedGame.isEmpty == false) { Button { guard let saved = savedGame.first else { return } difficulty = saved.currentDifficulty gameIsInSession = true isGameContinued = true } label: { ZStack { Rectangle() .fill(Color(red: 0.9, green: 0.2, blue: 1.0)) .frame(width: 300.0, height: 80.0) .cornerRadius(5.0) .padding(0.0) Text("Continue Game") .foregroundStyle(Color(red: 0.0, green: 0.0, blue: 0.0)) .font(.largeTitle) } } .padding(0.0) } } } .onAppear { print("Save count \(savedGame.count)") } } } struct GameBoard: View { @Environment(\.modelContext) private var context @Query private var savedGame: [ContinueGameData] @State var gameManager: GameManager @Binding var isGameContinued: Bool @Binding var difficulty: Difficulties @Binding var gameIsInSession: Bool init(isGameContinued: Binding<Bool>, difficulty: Binding<Difficulties>, gameIsInSession: Binding<Bool>) { self._isGameContinued = isGameContinued self._difficulty = difficulty self._gameIsInSession = gameIsInSession self._gameManager = State(initialValue: GameManager(difficulty: difficulty.wrappedValue)) } var body: some View { ZStack { Color(red: 0.0, green: 0.0, blue: 0.0, opacity: 0.00000000001) .ignoresSafeArea() .onTapGesture { gameManager.selectedCell = nil } VStack { SaveExitButton() { print("GameBoard context:", context) print("Start saving") if let game = gameManager.saveGame() { context.insert(game) } do { try context.save() print("Saved successfully") } catch { print("Save failed:", error) } difficulty = .none gameIsInSession = false } .... } @Model class ContinueGameData { var savedGameId: UUID var lastUpdated: Date var currentDifficulty: Difficulties var currentBoard: Data var currentNotesPerCell: Data var currentSecondsElapsed: Int var currentScore: Int var currentAttemptsLeft: Int init(savedGameId: UUID = UUID(), lastUpdated: Date = .now, currentDifficulty: Difficulties, currentBoard: Data, currentNotesPerCell: Data, currentSecondsElapsed: Int, currentScore: Int, currentAttemptsLeft: Int) { self.savedGameId = savedGameId self.lastUpdated = lastUpdated self.currentDifficulty = currentDifficulty self.currentBoard = currentBoard self.currentNotesPerCell = currentNotesPerCell self.currentSecondsElapsed = currentSecondsElapsed self.currentScore = currentScore self.currentAttemptsLeft = currentAttemptsLeft } }
Read Entire Article