How to Prevent Duplicates in Realmswift List

How do i prevent duplicates in RealmSwift List?

It depends on what kind of data coming from the server. If entire playlist data always come (you can always replace existing playlist data), you can just remove the list to empty, then append them.

realm.write {
user.playlists.removeAll() // empty playlists before adding

for playlistData in allPlaylistData {
let playlist = Playlist()
...
user.playlists.append(playlist)
}
}

If differential data coming from the server (also some are duplicated), you have to check whether the data already exists.

realm.write {
for playlistData in allPlaylistData {
let playlist = Playlist()
...

realm.add(playlist, update: true) // Must add to Realm before check

guard let index = user.playlists.indexOf(playlist) else {
// Nothing to do if exists
continue
}
user.playlists.append(playlist)
}
}

Proper way of avoiding duplicate object in Realm?

Depending on whether you want to update the existing object with new data or do nothing if it exists already, you have two alternatives.

If you want to do nothing if it already exists, you can use Realm.object(ofType:,forPrimaryKey:).

let existingPerson = realm.object(ofType: Person.self, forPrimaryKey: primaryKey)

if let existingPerson = existingPerson {
// Person already exists, act accordingly
} else {
// Add person
}

If you want to update the object if it exists and add it if it doesn't, you can simply use realm.add(_:,update:).

do {
try realm.write {
realm.add(personObject,update:true)
}
}

How to protect duplicate record insertion in realm

Your NotificationList needs a primary key.

Set the primary key to your object like seen below:

class NotificationList: Object {
dynamic var title = ""
dynamic var body = ""
dynamic var createdAt = NSDate()
dynamic var id = 0
let notifications = List<Notification>()

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

Then add the object using add(_:update:):

realm.add(newNotification, update: true)

If the id exists, it will update the data.

Avoid duplication in array of custom object in realm database. When Primary key is exist in the relational table only

You can just use Set to get rid of the duplicates before adding your objects to a List. Just make sure you make your types conform to Hashable that you want to add to a Set.

Some general advice: you don't need to create CodingKeys when the property names match the JSON keys unless you create a custom init(from decoder:) method and you don't need to create a custom init(from:) method unless you do some custom stuff, like use decodeIfPresent and filter duplicate objects. For Playlists and Tracks, you can rely on the synthetised initializer.

You also don't need to add elements from an array to a List in a loop, just use append(objectsIn:), which accepts a Sequence as its input argument.

class Songs: Object, Decodable {
let playlists = List<Playlists>()
let tracks = List<Tracks>()

enum CodingKeys: String, CodingKey {
case playlists, tracks
}

required convenience public init(from decoder: Decoder) throws {
self.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
if let playLists = try container.decodeIfPresent([Playlists].self, forKey: .playlists){
let uniquePlaylists = Set(playLists)
self.playlists.append(objectsIn: uniquePlaylists)
}

if let tracksList = try container.decodeIfPresent([Tracks].self, forKey: .tracks){
let uniqueTrackList = Set(tracksList)
self.tracks.append(objectsIn: uniqueTrackList)
}
}
}

class Playlists: Object, Codable, Hashable {
@objc dynamic var id: String = ""
@objc dynamic var name: String = ""
@objc dynamic var duration: Int = 0

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

}

class Tracks: Object, Codable, Hashable {
@objc dynamic var id: String = ""
@objc dynamic var name: String = ""
@objc dynamic var artist: Int = 0

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

If you want to make sure you don't add any objects twice to Realm, you need to use add(_:,update:) instead of add and use the primaryKey to avoid adding elements with the same keys.

SongsData = try jsonDecoder.decode(Songs.self, from: data)
let realm = try! Realm()
try! realm.write {
realm.add(SongsData, update: true)
} catch {
Logger.log.printOnConsole(string: "Unable to convert to data")
}

Preventing duplicate storage to realm

The issue is that in the createOfflineList method you create a new OfflineModel, which generates a random id using UUID().uuidString and hence you cannot have duplicate models from Realm's point of view, since id, which is used as the primary key will always be different. You'll need to use title (or any other non-random property that you actually want to use to identify your model instances) as the primary key.

class OfflineModel: Object {
@objc dynamic var photo: Data? = nil
@objc dynamic var title : String = ""
@objc dynamic var createdDate: Date?

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

RealmSwift + Duplicates of Data

We can ensure, we check if the person already exist, and if so, don't create and add the dogs:

func saveFunc() {

do {

let realm = try Realm()
if let person = realm.objectForPrimaryKey(Person.self, key: personId){
//Nothing needs be done.

}else {

//Create Person and dogs and relate them.

let newPerson = Person()
newPerson.id.value = personId
newPerson.name = personName

let newDog = Dog()
if dogNameArray.count > 0 {
for dog in dogNameArray {
newDog.name = dog
newPerson.dog.append(newDog)
}
}

let realm = try Realm()
realm.beginWrite()
realm.create(Person.self, value: newPerson, update: true)
try realm.commitWrite()
}

} catch {
print("create and updating error"
}


Related Topics



Leave a reply



Submit