Delonn
Delonn

Reputation: 159

How do we compare the value in RealmSwift List and Json nested Array?

Realmswift Data Model

class User {
    let id = RealmOptional<Int>()
    dynamic var name = ""
    let albums = List<Album>()

    override static func primaryKey() -> String {
        return "id"
    }
}

class Album: Object {
    dynamic albumName = ""
    let imageIDs = List<ImageID>()
}

class ImageID: Object {
    let imageId = RealmOptional<Int>()
}

JSON data

{
 "10001": {
     "id" : 10001,
     "name": "John",
     "album": {
         "albums": [
           {
            "albumName": "Summer1999",
            "imageIds": [11223, 11224, 11227]
           },
           {
            "albumName": "Xmas1999",
            "imageIds": [22991, 22997]
           },
           {
            "albumName": "NewYear2000",
            "imageIds": [5556, 776, 83224, 87543]
           }
          ]
      }
   }
}

I have the above json data and I m using SwiftyJSON to parse the data then write into realm. Everything is working great except for checking and updating of data (for example imageIds on json file have changed).

Question: How do i compare the JSON arrays and RealmSwift List to determine it any updates need to be written into the database?

Upvotes: 0

Views: 747

Answers (2)

TiM
TiM

Reputation: 15991

I'm afraid there's probably no easy answer to this. There's no mechanism in Realm to compare the contents of a Realm Object to an external object to see if their data matches. You would need to iterate through each object in the Realm object and manually compare it.

This wouldn't be too much code to write (Since you can get a list of all of the Realm file's properties via the objectSchema property of Realm objects, and then use key-value coding to pull them out in a single for loop), but would still be a fair amount of overhead to perform the compare.

That being said, if what you're wanting to look at is just certain properties that might change (i.e. like you said, just the imageIDs property), then you could easily just check the values you need.

What bcamur has suggested is definitely the quickest (And usually preferred for JSON handing) solution here. As long as you've set your primary key properly, you can call Realm.add(_:, update:) with update set to true to update the object.

Please keep in mind this doesn't merge the new data with what was already in Realm; it'll completely overwrite the old object with the new values, which if it sounds like your ID numbers are changing, would be the best course of action.

Upvotes: 0

bcamur
bcamur

Reputation: 894

You can take advantage of your primary key here. As Realm Swift documentation states:

Creating and Updating Objects With Primary Keys: If your model class includes a primary key, you can have Realm intelligently update or add objects based off of their primary key values using Realm().add(_:update:).

So (I assume that you get the JSON from some kind of a request (REST etc.) and then parse it with SwiftyJSON to create a 'User' object) you can treat the new 'User' object as regular new 'User' and try to add it to Realm as usual, but 'update' parameter must be 'true'. If there already was a user with the id of the 'User' object you are trying to add, it will just update the existing 'User' i.e. changing its modified values from the new 'User' created by parsing new JSON data. This might look something like this:

//Parse JSON and create a 'User'
let newUserFromJSON = parseAndCreateUserFromJSON(JSONData)

let realm = try! Realm()

do {
    try realm.write {
        realm.add(newUserFromJSON, update: true)
    }
} catch let error as NSError {
    print("error writing to realm: \(error.description) & \(error)")
} catch {
    print("error writing to realm: UNKNOWN ERROR")
}

Upvotes: 1

Related Questions