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.
Related
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
Using the (modified) examples in the Realm Swift documentation:
class Dog: Object {
dynamic var name = ""
dynamic var age = 0
let puppies = List<Puppies>()
}
class Person: Object {
dynamic var name = ""
dynamic var picture: NSData? = nil // optionals supported
let dogs = List<Dog>()
}
class Puppies: Object {
dynamic var name = ""
}
Let's assume that the Person.name = Bob, and that Bob has several dogs added to his dogs List. I have added another model class called Puppies, which would represent puppies that belong to Bob's dogs. (Apparently Bob owns a kennel.)
How would I get the values to display the names of Bob's dogs and the number of puppies belonging to each dog in a UITableview?
More specifically, what is the code to extract the property values of the List of dogs that belong to Bob. I assume that once I get those values it won't be difficult to list them in the tableview cells.
I decide to use the slightly modified example from the documentation instead of my own code so that those who read this won't have to try and interpret my code, and be able to focus on the solution.
I have been able to save my data and believe I have made the relationships between the objects link properly, but don't know how to get the values of the List objects, based on the primary key I have in my top level model. The problem I have is that (using the example above): the puppies know what dog they belong to, and the dog knows the person it belongs to, but the inverse relationships don't seem to work.
(By the way; I used the LinkingObject examples in the documentation in a playground and it throws and error. I'm not sure if the examples are incomplete in some way.)
In the Realm Browser (displaying the Person object) I can see the data as entered but the link that shows [Dog] has a 0 next to it and when I click on the link, the table that shows is blank. Maybe solving that issues will be the answer to make everything else work.
Please excuse my ignorance. I'm still learning.
Thanks to Ahmad F. for pointing me in the right direction.
Here is the answer:
I did not know how to append to the list property in each of the object classes. Following the example above, it is done by creating a variable that holds the Person object. Then the realm.write function would look something like this.
newDog = Dog()
newDog.name = "Phydeaux"
.....
try! realm.write {
currentPerson?.dogs.append(newDog)
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.
I am study about Realm db, this db is nice as compare with core data but I am stuck on one place as follows:
I have two RLMObject in that I created relationship and I want to run join query (sub query) on that, but I can't do that.
first object (table) in Ralm
class Dog : RLMObject
{
dynamic var name = ""
dynamic var age = 0
// create variable of Owner object
dynamic var owner = RLMArray(objectClassName: "Owner")
override class func primaryKey() -> String!{
return "name"
}
}
second object (table) in Ralm
class Owner : RLMObject{
dynamic var myName = ""
}
so I want to fetch only those Dog names which belong with owner name 'ram'
I tried following sub query
var dog = Dog.allObjects().objectsWithPredicate(NSPredicate(format:"SUBQUERY(Owner, $owner, $owner.myName = 'ram')", argumentArray: nil))
but app is crashing with following error
RealTest[1701:17960] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "SUBQUERY(owner, $owner, $owner.myName = 'ram')"'
also I search it on net I found that realm.objects but it gave me error about not found.
Thanks in advance!
Your predicate should look like this:
let predicate = NSPredicate(format:"SUBQUERY(Owner, $owner, $owner.myName = 'ram') .#count > 0", argumentArray: nil)
The idea here is to make sure you add .# count > 0 at the end, as the predicate needs to return true or false for it to work.
This can be achieved using a query like:
Dog.allObjects().objectsWhere("ANY owner.myName = 'ram'")
SUBQUERY is only necessary if you have multiple constraints on the target of the relationship that must all be fulfilled by a single row, or if you wish to express a constraint other than ANY / ALL / NONE on the number of rows that match.
That said, as of Realm Objective-C and Swift 0.98.0 SUBQUERY is now supported.
While Realm supports filtering objects via NSPredicate, at this time of writing, Realm's implementation of NSPredicate yet support every single type of keyword that the native Apple frameworks do, including SUBQUERY. Realm provides an NSPredicate cheat sheet on its website, outlining which types of queries it presently supports.
That being said, if you already have an Owner object at this point, you can actually use another Realm method on the Owner object ([RLMObject linkingObjectsOfClass:forProperty:]) to find out which Dog objects are referencing it.
Finally, that realm.objects error is because that syntax is from the native Swift version of Realm, and the code you're using here is the Objective-C version of Realm, bridged over to Swift.
Let me know if you need any more clarification!
I am not sure is this is correct behaviour or if its unintended. I have setup StealthFighter so that it returns a class type computed property variable called ammunition.
func globalTests() {
println("globalTests")
println("AMMUNITION: \(StealthFighter.ammunition)")
var myStealthFighter = StealthFighter()
println("MISSILES: \(myStealthFighter.missiles)")
println("AMMUNITION: \(myStealthFighter.ammunition)") // ERROR
}
class StealthFighter {
class var ammunition:Int {
return 500;
}
var missiles: Int = 5
}
When directly accessing the class StealthFighter this works fine and returns 500 as expected. But if I create and instance myStealthFighter and then try and access the class property on the instance I get the error: 'StealthFighter' does not have a member named 'ammunition' I can't find any mention of this, I am assuming from this that class properties are accessible only via the class? and not on any instances created from it? I just want to make sure I am understanding this correctly ...
EDIT:
So I have probably worded the type variable name wrong as it should probably be maxAmmunition to signify that StealthFighters can only take 500 rounds. I can see the point, if you want the maxAmmunition for the class then you ask the class.
As #Kreiri and #0x7fffffff points out it does seem that you can ask the instance what the class ammunition (or maxAmmunition) is by using dynamicType.
println("CLASS - AMMUNITION: \(StealthFighter.ammunition)")
var myStealthFighter = StealthFighter()
println("INSTA - AMMUNITION: \(myStealthFighter.dynamicType.ammunition)")
.
// OUTPUT
// CLASS - AMMUNITION: 500
// INSTA - AMMUNITION: 500
Your assumption is correct. Type variables are only meant to be accessed directly from the class. If you want to get at them from an instance, you can do so by accessing the dynamicType property on your instance, like so.
let theFighter = StealthFighter()
let missiles = theFighter.dynamicType.missiles
println(missiles)
However, I don't think that this is the correct approach for you to be taking here. Assuming that you want to have one class "StealthFighter", and possibly multiple instances of that class, each with the ability to have its own number of missiles independent of the others, you should probably make this an instance variable by simply ditching the class keyword.
dynamicType allows access instance’s runtime type as a value, so accessing class property from instance would look like this:
var myStealthFighter = StealthFighter()
myStealthFighter.dynamicType.ammunition
Works in playground, at least.
These properties are known as Type properties in swift. It should be called on its type ie class name, not on instance. Type properties holds same value across all the instances of the class just like static constant in C.
Querying and Setting Type Properties
Type properties are queried and set with dot syntax, just like instance properties. However, type properties are queried and set on the type, not on an instance of that type
Excerpt from : swift programming language
Swift 4:
var myStealthFighter = StealthFighter()
type(of: myStealthFighter).ammunition
Yes. This is a correct behaviour. These Type Properties can only be accessed over the Type and are not available on the instance itself.
In the Swift Book from Apple it is described in the section "Type Properties" (Page 205).
Swift Type Properties
“Unlike stored instance properties, you must always give stored type properties a default value. This is because the type itself does not have an initializer that can assign a value to a stored type property at initialization time"