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)
}
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
}
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
Swift: Nsstatusitem Menu Behaviour in 10.10 (E.G. Show Only on Right Mouse Click)
Swift - Segue from Button Inside a Cell
How to Define an Extension to Collectiontype So That Its Methods Are Available to Dictionaries
Curl with Alamofire - Swift - Multipart/Form-Data
iOS Swift Didbegincontact Not Being Called
How to Check If Cmtime Is Valid in Swift
New Fuitableviewdatasource - How to Use? Swift 3
Core Data: Rename Attribute Without Having Issues with Users and Their Current Data
Swift. Get Binary String from an Integer
A Way to Inherit from Multiple Classes
Swift: Lazily Encapsulating Chains of Map, Filter, Flatmap
How to Duplicate a Sprite in Sprite Kit and Have Them Behave Differently
Setting Arkit Orientation via Swift
Uisearchbar's Set_Cancelbuttontext: Ivar Is Prohibited
Getting an Issue with Upgrade to Xcode 10.2