1

When my app is first downloaded, it takes a JSON file and serialized it into a Realm database. This was the only way I found that would allow me to pre-populate a realm database and at the same time make it writable. Since Realm doesn't accept lists of strings, I had to make an object called MyString with a text property.

The issue:
My app re-serializes the JSON every new update to account for changes in the database. Only the read-only properties are re-written. This is how I do it:

func serialize() {
    let path = Bundle.main.path(forResource: "JSONFile", ofType: "json")
    let url = URL(fileURLWithPath: path!)
    let jsonDecoder = JSONDecoder()
    do {
        let data = try Data(contentsOf: url)
        let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
        guard json is [AnyObject] else { assert(false, "failed to parse"); return }
        do {
            let myItems = try jsonDecoder.decode([Item].self, from: data)
            for myItem in myItems {
                try! realm.write {
                    realm.create(Item.self, value: [
                        "id": myItem.id,
                        "entitle": myItem.entitle,
                        "artitle": myItem.artitle,
                        "submenus": myItem.submenus, // This is a List<MyString>
                        "dates": myItem.dates        // This is a List<MyString>
                    ], update: .modified)
                    // Other write-only propeties are left out to not overwrite the user's changes
                }
            }
        } catch let error { print("failed to convert data: \(error)") }
    } catch let error { print(error) }
}

Now, every time my app updates (and the first time the app is opened), this code runs and redoes all of the serialization. The update: .modified is what allows me to not duplicate the Item object, which is great. However, every time it runs, it makes a new MyString object, rather than overwriting it. Now everyone has each MyString object duplicated like 5 times and will increase in every update. Is there a way to:

  1. Delete all duplicates for current users? 4 of the 5 duplicates are not being used. they just exist in the database. I can't delete all MyString objects before every serialization because some of them are write-only properties that the user has entered. Deleting all of these will also delete the user's data.
  2. Make it where it doesn't duplicate every time? I tried adding adding a primaryKey as name, but it gives me this error: Primary key property 'class_MyString.text' has duplicate values after migration.. The thing is, they are not all unique. Many of them share similar text, so how do I differentiate between them?
enigrify
  • 281
  • 3
  • 17

1 Answers1

0

You can pre-populate a Realm file and include it as part of your app's bundle. Please see this documentation: https://realm.io/docs/swift/latest/#bundling-a-realm

Also use realm.add(Item(), update: .modified) when adding/updating an object which already exists.