0

Currently I am checking whether the object already exists in core data based on id and then updating and inserting. Is there any better way to do it? Have added "id" as a unique constraint, Which prevents inserting of objects with same "id". Does inserting just update the existing object with same id?

   @nonobjc public class func saveUserMovies(movieJSON: [[String: Any]], user: UserProfile, isFavorites: Bool = false, isWatchlisted: Bool = false) {
        let context = MMPersistentStore.sharedInstance.privateManagedObjectContext
        for movie in movieJSON {
            let movieID = movie["id"] as! Int
            let fetchMovieWithIDRequest = fetchMovieRequest()
            let moviePredicate = NSPredicate(format: "id == %d", movieID)
            let sortDiscriptor = NSSortDescriptor(key: "id", ascending: false)
            fetchMovieWithIDRequest.sortDescriptors = [sortDiscriptor]
            fetchMovieWithIDRequest.predicate = moviePredicate
            
            var userMovie: UserMovie?
            context.performAndWait {
                do {
                    userMovie = try fetchMovieWithIDRequest.execute().first
                } catch {
                    print(MMErrorStrings.coreDataFetchError)
                }
                }
                if let fetchedMovie = userMovie {
                    fetchedMovie.genreIds = movie["genre_ids"] as? [Int64]
                    fetchedMovie.adult = movie["adult"] as? Bool ?? false
                    if isFavorites {
                      fetchedMovie.isFavorite = isFavorites
                    } else {
                        fetchedMovie.isWatchlisted = isWatchlisted
                    }
                    
                    fetchedMovie.video = movie["video"] as? Bool ?? false
                    fetchedMovie.backdropPath = movie["backdrop_path"] as? String
                    fetchedMovie.originalLanguage = movie["original_language"] as? String
                    fetchedMovie.originalTitle = movie["original_title"] as? String
                    fetchedMovie.overview = movie["overview"] as? String
                    fetchedMovie.posterPath = movie["poster_path"] as? String
                    fetchedMovie.releaseDate = movie["release_date"] as? String
                    fetchedMovie.releaseYear = String(fetchedMovie.releaseDate?.prefix(4) ?? "")
                    fetchedMovie.title = movie["title"] as? String
                    fetchedMovie.popularity = movie["popularity"] as? Double ?? 0.0
                    fetchedMovie.voteCount = movie["voteCount"] as? Int64 ?? 0
                    fetchedMovie.voteAverage = movie["voteAverage"] as? Double ?? 0.0
                    
                    MMPersistentStore.sharedInstance.save(context: context)
                } else {
                    let fetchedMovie = UserMovie(context: context)
                    fetchedMovie.id = movie["id"] as? Int64 ?? 0
                    fetchedMovie.user = user
                    fetchedMovie.genreIds = movie["genre_ids"] as? [Int64]
                    fetchedMovie.adult = movie["adult"] as? Bool ?? false
                    if isFavorites {
                      fetchedMovie.isFavorite = isFavorites
                    } else {
                        fetchedMovie.isWatchlisted = isWatchlisted
                    }
                    
                    fetchedMovie.video = movie["video"] as? Bool ?? false
                    fetchedMovie.backdropPath = movie["backdrop_path"] as? String
                    fetchedMovie.originalLanguage = movie["original_language"] as? String
                    fetchedMovie.originalTitle = movie["original_title"] as? String
                    fetchedMovie.overview = movie["overview"] as? String
                    fetchedMovie.posterPath = movie["poster_path"] as? String
                    fetchedMovie.releaseDate = movie["release_date"] as? String
                    fetchedMovie.releaseYear = String(fetchedMovie.releaseDate?.prefix(4) ?? "")
                    fetchedMovie.title = movie["title"] as? String
                    fetchedMovie.popularity = movie["popularity"] as? Double ?? 0.0
                    fetchedMovie.voteCount = movie["voteCount"] as? Int64 ?? 0
                    fetchedMovie.voteAverage = movie["voteAverage"] as? Double ?? 0.0
                    
                    MMPersistentStore.sharedInstance.save(context: context)
                }
            }
        }
    }

enter image description here

Pranay Chander
  • 461
  • 5
  • 12

1 Answers1

0
  1. Have added "id" as a unique constraint, Which prevents inserting of objects with same "id".
  • I didn't use it before yet
  1. Does inserting just update the existing object with same id?
  • No, it'll insert the new object.

For your case, you could make a refactoring, please refer the findOrCreate function in https://github.com/objcio/core-data/blob/master/SharedCode/Managed.swift

It'll help you avoid duplicated code.

One more thing, your request doesn't need the sortDescriptor, and it should have the limit = 1, and returnObjectAsFaults = false for optimisation.

After that, you just need to make sure your function is called in the same context to avoid duplications.

nghiahoang
  • 538
  • 4
  • 10
  • 1
    Core data _does have_ unique constraint, https://stackoverflow.com/questions/21130427/how-to-add-unique-constraints-for-some-fields-in-core-data – Joakim Danielson Aug 05 '20 at 11:49
  • "I didn't use it before yet", this isn't really helpful for OP. How is that linked, 5 year old code, any better than what OP is doing now? Please add an explanation of what the linked code does and how it is an improvement. – Joakim Danielson Aug 05 '20 at 11:59