Realm, Avoid to Store Some Property

Realm, avoid to store some property

Check out the RealmSwift docs about Ignoring properties. There is some sample code included on that section:

class Person: Object {
dynamic var tmpID = 0
var name: String { // read-only properties are automatically ignored
return "\(firstName) \(lastName)"
}
dynamic var firstName = ""
dynamic var lastName = ""

override static func ignoredProperties() -> [String] {
return ["tmpID"]
}
}

Prevent Realm from overwriting a property when updating an Object

There are two ways to solve this:

1. Use an Ignored Property:

You can tell Realm that a certain property should not be persisted. To prevent that your favorite property will be persisted by Realm you have to do this:

class Pet: Object{
dynamic var id: Int = 1
dynamic var title: String = ""
dynamic var type: String = ""
dynamic var favorite: Bool = false

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

override static func ignoredProperties() -> [String] {
return ["favorite"]
}
}

or you could

2. Do a partial update

Or you could tell Realm explicitly which properties should be updated when you update your Pet object:

try! realm.write {
realm.create(Pet.self, value: ["id": 2, "name": "Dog", "type": "German Shepard"], update: true)
}

This way the favorite property will not be changed.

Conclusion

There is one big difference between the two approaches:

Ignored Property: Realm won't store the favorite property at all. It is your responsibility to keep track of them.

Partial Update: Realm will store the 'favorite' property, but it won't be updated.

I suppose that the partial updates are what you need for your purpose.

Preserving Realm property value when updating object

The short answer is that partial updates of an object cannot be performed by passing an instance of an Object subclass to Realm.add(_:update:). The reason for this is that there's no way to represent don't update this property for a property on your Object subclass. You'll instead want to pass a dictionary to Realm.create(_:value:update:), where the absence of a given key represents don't update this property.

Realm list property not saving data

Your Schools declaration is flawed. You shouldn't declare a List as dynamic or mutable, nor should you make it Optional. As the docs clearly state, let listTeachers = List<Teachers>() is the correct way to declare a many-to-many relationship.

Storing a property of type Array is also not supported by Realm, so you should delete the teachersList : [Teachers]? property.

@objcMembers public class Schools : Object {
dynamic var Id : String = ""
dynamic var UserId : Int64 = 0
dynamic var Name : String? = ""
let listTeachers = List<Teachers>()
}

Why can't I use private on a Realm property

This is tough to answer because our project has a similar setup and it's working. So let me try to present an answer via an example of what how our code looks.

First, the realm object. the object has an id, a name and then a visible property revisionType which is assigned via an enum (not managed by Realm) that's backed by a private revisionTypeRaw which is managed by realm.

class PlaylistRealmObject: Object {
enum RevisionTypeEnum: String {
case type_a = "a"
case type_b = "b"
}

@objc dynamic var list_id = UUID().uuidString
@objc dynamic var list_name = ""

@objc private dynamic var revisionTypeRaw: String = ""
var revisionType: RevisionTypeEnum {
get {
let x = RevisionTypeEnum(rawValue: revisionTypeRaw)!
return x
}
set {
revisionTypeRaw = newValue.rawValue
}
}

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

then we create a couple of playlists and store in Realm

let newAgePlaylist = PlaylistRealmObject()
newAgePlaylist.list_name = "New Age"
newAgePlaylist.revisionType = .type_a

let classicRockPlaylist = PlaylistRealmObject()
classicRockPlaylist.list_name = "Classic Rock"
classicRockPlaylist.revisionType = .type_b

realm.add(newAgePlaylist)
realm.add(classicRockPlaylist)

then to check it, load in all of the playlists and print to console depending on what type of revision they are

let playlistResults = realm.objects(PlaylistRealmObject.self)
for playlist in playlistResults {
let name = playlist.list_name
if playlist.revisionType == .type_a {
print("name: \(name) is a type_a playlist")
} else {
print("name: \(name) is a type_b playlist")
}
}

RealmSwift not saving properties

I am posting this answer for clarity and to demonstrate realm functionality.

Given a person object with a primary key

class PersonClass: Object {
@objc dynamic var _id = 0
@objc dynamic var name = "Jay"

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

When the object is instantiated, it will default to a primary key of 0, and the name property will be Jay

let person = PersonClass()

let realm = try! Realm()

try! realm.write {
realm.add(person)
}

Sample Image

As long as that object has not gone out of scope, the name can be changed. So let's instantiate the same object but change the name after

let person = PersonClass()

let realm = try! Realm()

try! realm.write {
realm.add(person) //creates the Jay object
}

try! realm.write {
person.name = "Cindy" // name of that managed object is now Cindy
}

Sample Image

You can even read the object from realm, and update it later. Suppose in one part of your code the Jay PersonClass was written but then at a later time you wanted to update the name to Leroy

let realm = try! Realm()

if let jayObject = realm.objects(PersonClass.self).filter("name == 'Jay'").first {
try! realm.write {
jayObject.name = "Leroy"
}
}

The end result of running that code is the PersonClass object that initially had a name of Jay being updated to a new name of Leroy

A final note that Integer primary keys can be troublesome. I would suggest using the ObjectId() class to generate unique primary keys. Please see the Realm Documentation on Primary Keys for further reading.

How to keep certain changed properties unchanged in Realm migration - Swift

I figured it out. You have to do a partial serialization.

Changed this:

realm.add(thing, update: .modified)

To:

realm.create(Thing.self, value: [
"id": thing.id,
"propertyOne": thing.propertyOne
// Leave out propertyTwo to leave it unchanged
], update: .modified)


Related Topics



Leave a reply



Submit