swiftswiftuicloudkitswiftdata

Persisting data with objects that can have default predefined values and user generated values


I'm developing an app using SwiftData and CloudKit that presents the user with a selectable List of movie genres to choose from, populated from an enum and another array of objects (more on this in a second):

enum MovieGenre: String, Codable, CaseIterable
{
    case drama = "Drama"
    case comedy = "Teleplay"
    case action = "Action"
    case horror = "Horror"
    case thriller = "Thriller"
    case musical = "Musical"
    case animated = "Animated"
}

On this List, there is a Button that allows the user to add their own genre and for this I have the class model CustomMovieGenre:

import Foundation
import SwiftData

@Model
class CustomMovieGenre
{
    var name: String = ""
    
    init(name: String)
    {
        self.name = name
    }
} 

Once they add a CustomMovieGenre, it will be appended to the List of movie genres. Since I'm wanting a MovieGenre item to store other persistable model data (like arrays of movies in that genre, etc), I'm thinking of eliminating the enum and combining CustomMovieGenre and MovieGenre into one class called MovieGenre (this would also simplify the code to display the List).

As I would still be wanting to have the default genres, I'm wondering if there is a common pattern for accomplishing this? As of now, when the app launches, I think I would have to check and see if the default MovieGenre existed, and if not, create them. However, I want to avoid having to do that, if possible.


Solution

  • Eliminating the enum and having a single MovieGenre class is the right move. Your default genres from the enum would then be predefined MovieGenre instances and pre-populated as part of an initial app setup/onboarding.

    If you download the files from Apple's SwiftData tutorial, you'll see how they go about it by looking at the SampleData folder. The files there include the functions for inserting the sample data, as well as resetting it. Keep that downloaded project handy, it will be a good reference for later.

    You wouldn't have to check if the default genres existed on every app launch, since you would only import the default data once, as part of onboarding. You would check if onboarding was done, which assumes the genres were once populated, since the user may have customized them since, including deleting some of the default ones.

    Depending on the needs of the project, if some genres (or more generically, predefined class instances) should not be deletable by the user at any point, you can include a model/class bool property like isReservedGenre and use it in the app logic with the necessary checks to disable deletion if reserved.