Update Realm objects - SwiftUI - swift

I need to update all the objects in the database, when I try it, it says:
Thread 1: "Attempting to modify a frozen object - call thaw on the Object instance first."
I have the following:
#ObservedRealmObject var meal: MealTracking
#ObservedResults(MealTracking.self) var mealTracking
mealTracking is the one that contains everything and meal is the single object in the current view.
So once I update the name on that single object (meal), I want to update the name on all other objects. So I'm doing:
for (index, meal) in self.mealTracking.enumerated() {
$mealTracking.wrappedValue[index].mealName = ""
}
and I get the error of not being able to update the objects.
I also tried it like $mealTracking[index].mealName.wrappedValue = "" and gives another error: Referencing subscript 'subscript(_:)' requires wrapped value of type 'Results<MealTracking>'
For a the single object on the current view I can update it with:
$meal.mealName.wrappedValue = "some stuff", the problem is when attempting to update All objects
How can I update all the objects?

#ObservedRealmObject is a frozen object. If you want to modify the properties of an #ObservedRealmObject directly in a write transaction, you must .thaw() it first.
In your case something like :
mealName.thaw()?.name = ""
More information :
https://www.mongodb.com/docs/realm/sdk/swift/swiftui/
https://www.mongodb.com/community/forums/t/freeze-frozen-objects-and-thawing/15706/5

Related

RxSwift - change specific object in PublishSubject on event

struct Contact : Codable, Hashable {
var id : String
...
}
I use PublishSubject to feed the data to the UITableView
let contacts : PublishSubject<[Contact]> = PublishSubject()
And when the value is changed on the other view controller, I want to change the specific value in the array.
I want to change the Contact object with the specific id.
contacts.filter {$0.id == contactId}[0].someKey = someValue
How can I do this with RxSwift?
Understand that a PublishSubject doesn't contain any state so there is nothing in it that you can change. Instead, you emit a new array from the publish subject with a new contact that has the new value.
Somewhere in your code, you are calling onNext(_:) on the subject (or connecting it to an Observable that is doing that. We would need to see that code to help you solve your problem.

Realm Migration - Changing Name of Class (for complex class)

I'm not able to change the class name of a Realm Object that has properties pointing to other Realm Objects. A class like this, for example.
class OldClass: Object {
var id: String!
var dog: Dog! //this is a Realm Object (with its own table)
}
I've seen the simple examples of how to do this.
migration.enumerateObjects(ofType: "OldClass", { (oldObject, newObject) in
migration.create("NewClass", value: oldObject!)
})
I expect the above would work if the schemas for both OldClass and NewClass were the same, AND if all the properties were non-Realm objects. If the schemas are different, I've gathered that you can do something like this.
migration.enumerateObjects(ofType: "OldClass", { (oldObject, newObject) in
let obj = migration.create("NewClass")
obj["id"] = (oldObject["id"] as! String)
obj["newPropertyName"] = (oldObject!["oldPropertyName"] as! Int)
})
Neither of these example seem to work when your object has a property pointing to another Realm object though. At least this is what I suspect, since I get RLMException 'Can't create object with existing primary key value'.
My suspicion is that the 'existing primary key' is referring to the Dog object, and that in migrating from NewClass to OldClass, the migration is trying to re-create the Dog object (which already exists).
How do I properly perform this type of migration?
Unfortunately this feature is not implemented, we track it in https://github.com/realm/realm-cocoa/issues/2162. You can also find some useful info at https://github.com/realm/realm-cocoa/issues/4366.

How to change Class object name in a loop

So I have Class
class MyClass
....do things...
and I add objects to it with
ObjName = MyClass(things)
and my problem is that when I add ObjName to MyClass in a loop, I can't figure out a way to create a new object name each loop so it keeps overwriting the only Obj this ends up creating. I tried adding a list as in
ObjName[i] = MyClass(things)
but it wouldn't work.
Here is what I'm trying to do specifically (edited for clarity):
So when I add objects to MyClass, the name of the object added should be callable with input, like so:
somename = input("objname: ") # User input decides how the object values can be called
TempObjName = MyClass(things) # Values of the specific object, will contain more than one unique object
*...*
somename.someattribute() ## 2 different
somename2.someattribute() ## values, sets or etc
Try this:
ObjList = []
for i in whatever:
temp = MyClass(things)
ObjList.extend(temp)
I wasn't able to create the function I wanted per-say, but because my code had a dictionary that saved the obj name and obj value in it, I was able to do what I initially wanted to do by rerunning the requested name from the dictionary in the Class.

Realm object property misses its value, but I can see it when printing the whole object

I stumbled upon a weird thing when trying to fetch an object from my Realm (iOS, Swift, Realm version 0.98.2)
print("speaker:")
print(RealmProvider.appRealm.objects(FavoriteSpeaker).first!)
Correctly dumps my object in the console:
speaker:
FavoriteSpeaker {
name = Ashley Nelson-Hornstein;
}
But when I try to get the name property's value:
print("speaker name:")
print(RealmProvider.appRealm.objects(FavoriteSpeaker).first!.name)
I get an empty string 🤔
speaker name:
The four lines are together in my model's init method
Update 1: I found an answer that suggests that you merely don't see the values when printed in the Console: Realm object is missing all properties except primaryKey but I also tried displaying the name property via an alert view and that is also empty.
Update 2: Just to make sure that everything happens sequentially and on the same thread I did this:
let favorite1 = FavoriteSpeaker()
favorite1.name = "Debbie Downer"
try! RealmProvider.appRealm.write {
RealmProvider.appRealm.deleteAll()
RealmProvider.appRealm.add(favorite1)
}
print("speaker:")
print(RealmProvider.appRealm.objects(FavoriteSpeaker.self).first!)
print("speaker name:")
print(RealmProvider.appRealm.objects(FavoriteSpeaker.self).first!.name)
But the result is the same - printing name prints an empty string
The name property is probably not declared as dynamic, which leads to it reading the nil value stored on the object itself rather than reading the data from the Realm.

Parse local datastore relation

I've a class called category, and I have retrieved my categories from local datastore through query.getFromLocalDataStore().
Next I've the following code
var userExpense = PFObject(className: "Expenses")
userExpense["category"] = category
userExpense.saveEventually()
userExpense.pin()
And now i'm getting this error,
{error={"__type":"Pointer","className":"Category","localId":"local_55876b12913120b9"} is not a valid Pointer, code=106}
Any idea why? I wanted
If I'm correct, you downloaded the category variable as a PFObject, not as a pointer. What you can do, is to create a pointer from your category with the method:
objectWithoutDataWithClassName:objectId:
and set that to userExpense["category"], and that will be a valid pointer.