UserDefault: Is there any solution to add Favorited Movies into UserDefault

59 Views Asked by At

the project is like this, i have a button of adding a movie into Favorited Movies page, and the user can delete the movie (.onDelete). but, the thing here is that whenever i delete the Movie from Favorites, and enter to the same Movie again it shows red button "Remove From Favorites".

furthermore, when i exit the app and try to add another Movie and the earlier Movie is already delete it reappears again above new added Movie.

//
//  TrackedMoviesViewModel.swift
//  moviefinder

import Foundation

class TrackedMoviesViewModel: ObservableObject {

    @Published var trackedMovies: [TrackedMovieModel] = []
    
    init() {
            fetchTrackedMovies()
        }
        
    let moviesKey: String = "trackedmovie_list"
    
    
    func addTrackedMovie(_ trackedMovie: TrackedMovieModel) {
        trackedMovies.append(trackedMovie)
        trackMovie()
    }
    
    func isMovieTracked(_ movie: TrackedMovieModel) -> Bool {
            return trackedMovies.contains { $0.id == movie.id }
        }
    
    
    func removeTrackedMovie(_ trackedMovie: TrackedMovieModel) {
        if let index = trackedMovies.firstIndex(where: { $0.id == trackedMovie.id }) {
            trackedMovies.remove(at: index)
            trackMovie()
        }
    }
    
    func deleteMovie(_trackedMovie: TrackedMovieModel){
        //trackedMovies.remove(atOffsets: )
    }
    
    private func trackMovie(){
        if let encodedData = try? JSONEncoder().encode(trackedMovies){
            UserDefaults.standard.set(encodedData, forKey: moviesKey)
        }
    }
    
    func fetchTrackedMovies() {
        if let data = UserDefaults.standard.data(forKey: moviesKey) {
            if let trackedMovies = try? JSONDecoder().decode([TrackedMovieModel].self, from: data) {
                self.trackedMovies = trackedMovies
            }
        }
    }

}
//
//  MediaDetailsViewModel.swift
//  moviefinder

import Foundation

class MediaDetailsViewModel: ObservableObject {
@Published var isTracked: Bool = false
var mediaId: Int? // Add this property to store the ID of the media
//var viewModel: TrackedMoviesViewModel

    init(initialIsTracked: Bool, mediaId: Int,trackedMoviesViewModel: TrackedMoviesViewModel) {
        self.isTracked = initialIsTracked
        self.mediaId = mediaId // Set the media ID during initialization
       // self.viewModel = trackedMoviesViewModel
        //updateTrackingStatus()
    }
    
    func toggleTracking() {
        isTracked.toggle()
        updateTrackingStatus(isTracked)
        
    }
    
     func updateTrackingStatus(_ isTracked: Bool) {
            let defaults = UserDefaults.standard
            if let mediaId = mediaId {
                defaults.set(isTracked, forKey: "isTracked_\(mediaId)")
            }
    }
    
    private func loadTrackingStatus() -> Bool {
        let defaults = UserDefaults.standard
        if let mediaId = mediaId {
            return defaults.bool(forKey: "isTracked_\(mediaId)")
        }
        return false
    }

}

This is the button that i have in MovieDetailsView (MediaDetailsView)

Button(action: {
                let trackedMovie = TrackedMovieModel(id: details.id, title: details.title, overview: details.overview, poster: details.poster)
                
                if trackedMoviesViewModel.isMovieTracked(trackedMovie) {
                        // Untrack the movie
                        trackedMoviesViewModel.removeTrackedMovie(trackedMovie)
                        } else {
                            // Track the movie
                            trackedMoviesViewModel.addTrackedMovie(trackedMovie)
                        }

                        // Toggle the tracking status
                        mediaDetailsViewModel.toggleTracking()
        
                }) {
                    Text(mediaDetailsViewModel.isTracked ? "Untrack the movie" : "Add to Tracked Movies")
                        .frame(height: 55)
                        .frame(maxWidth: .infinity)
                        .background(mediaDetailsViewModel.isTracked ? .red : .blue)
                        .foregroundColor(.white)
                        .cornerRadius(10)
                        .padding(.horizontal, 10)
                    }
0

There are 0 best solutions below