in my app there is a function that is analogous to liking a post. In my parse database, I have a "Like" class. In the Like class are 2 columns, one "from_user" that is a pointer column pointing to the user who liked it. The other is "to_post", pointing to the post that was liked. my code is:
var likeObject = PFObject(className: "Like")
likeObject["from_user"] = PFUser.currentUser()
likeObject["to_post"] = objectIDArray[0]
likeObject.saveInBackground()
For reference, the objectIDArray is an array that contains 1 element, the object ID of the given post that I want to like.
But when I try this, I get an error saying "expected type *Post, got String" which refers to the line of code:
likeObject["to_post"] = objectIDArray[0]
So how do I make it so that the object ID of the post (that I do have access to) can be used to point to that specific post?
thanks
What you want to do is use a pointer to the Post class.
The parameter you pass to the to_post key should be of type PFObject*, but instead you're passing a NSString* (the object id).
Considering you already have the ObjectID of the post, what you have to do is fetch the PFObject from that id and set it to your likeObject.
Try this:
var query = PFQuery(className:"Post")
query.getObjectInBackgroundWithId(objectIDArray[0]) {
(post: PFObject?, error: NSError?) -> Void in
if error == nil && post != nil {
likeObject["to_post"] = post
} else {
println(error)
}
}
Related
I have an application setup so that there is an array that contains objectId's that the current user is friends/connected with. I'm attempting to create a button that deletes a single objectId from that array (kind of like an unfriend button). I'm currently passing the objectId value from a query in one view controller to another view controller that actually contains the friends profile and the delete/unfriend button. I'm getting the actual objectId as a string in the friends profile and I can print the objectId but I can't seem to figure out a way to delete this single objectId from the array.
Using PFUser.currentUser()?.removeObject() gives me an invalid field name error.
Anyone have an insight for me?
Let me know if there is more clarification needed! Thanks in advance.
Update
I have tried to also utilize this as my object code. userObjectId is received from another view controller and grabs the proper objectId of what I'd like to remove from the current users "accepted" array. This code gives me an error of "NSInternalInconsistencyException reason: Tried to save an object with a pointer to a new, unsaved object" I've tried to remove this objectId from the array in several different ways but can't seem to get it to stick. Thanks again.
var userObjectId = ""
var object: PFObject = PFObject(className: "User")
object["objectId"] = userObjectID
PFUser.currentUser()?.removeObjectsInArray([object], forKey: "accepted")
PFUser.currentUser()?.saveInBackground()
let object = PFObject(withoutDataWithClassName: "Your Class", objectId: "objectId from array")
object.deleteInBackgroundWithBlock { (success, error) -> Void in
if error == nil && success == true {
//Delete the objectId from the array
}
}
This will also remove the object from any array that holds it.
I'm trying to increment a number in my parse table under the column "votes". Here's my code:
func upVote() {
var reviewQuery: PFQuery = PFQuery(className: "reviews")
reviewQuery.whereKey("content", equalTo: reviewTextView.text)
reviewQuery.findObjectsInBackgroundWithBlock{
(objects:[AnyObject]!, error:NSError!)->Void in
if error == nil{
for object in objects{
println(object)
let review:PFObject = object as! PFObject
review.incrementKey("votes", byAmount: 1)
}
}
}
}
When I print the object in the console I can see that it is the correct object that I'm looking for. It looks like this:
<reviews:ZqgSVL1Tsd:(null)> {
content = "njk\n";
reviewer = "<PFUser:6387CJtYI1>";
votes = 1;}
But when I look at my parse end, the number of votes has not changed. What am I doing wrong?
Save the object with
review.saveInBackground()
after incrementing the key.
After you modify an object, however small the modification, you must save it after. You are not saving your changes to the object review.
You have several options for saving, including save(), saveInBackground(), saveEventually(), and more. See the documentation for PFObject for more information:
https://www.parse.com/docs/ios/api/Classes/PFObject.html#//api/name/save
For example, you could save the object synchronously with
review.save() and you could save the object asynchronously with review.saveInBackground().
I'm struggling with retrieving an array of PFObjects that I stored on the PFUser.currentUser()
I have a custom subclass of PFObject: UNUser
Here's how I save the array of [UNUser] called favoriteDrivers:
if let currentUser = PFUser.currentUser() {
currentUser["favoriteDrivers"] = favoriteDrivers
currentUser.saveInBackgroundWithBlock({ (succes: Bool, error: NSError?) -> Void in
if succes {
}
})
}
If I retrieve the entry like this:
if let currentUser = PFUser.currentUser() {
var objects = currentUser["favoriteDrivers"]
println(objects) shows this in the console (the array in this trial has just one entry):
Optional(("<UNUser: 0x174138920, objectId: mEgJALLLA9, localId: (null)> {\n}"))
What is the best way to now fetch the referred to PFObjects and store them in an array of UNUser?
This is what I tried:
var relation = currentUser.relationForKey("favoriteDrivers")
relation.query()!.findObjectsInBackgroundWithBlock{ ( objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
let favoriteDrivers = objects as? [UNUser]
You're setting an array so you need to read an array, not a relation.
Your array is actually an array of pointers, which is exactly what you want, but you do need to ensure that you have all of the data for those pointers as by default (and as you can see in your log) you only get the class type and object ids.
To do that, get the array and then call fetchAllIfNeededInBackground:block: with the array. That will update any of the objects in the array that need it with the current data from the server. This is kind of like your relation query...
I need get an objectId from a user that is not the current user. I'm able to do a PFUserQuery to get the user that I'm looking for. I can see all the data there, I just can't extract the objectId.
var query = PFUser.query()
query!.whereKey("email", equalTo:userNameObject)
query!.findObjectsInBackgroundWithBlock {
(newUser: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
println(newUser) //This gets the correct User Record
var userVariable = newUser.objectId as String //Error: Type of expression is ambiguous without more context
Thanks!
In the above code, newUser is an array, not a PFUser object. If you're guaranteed to only get 0 or 1 user from your query, then you should use getFirstObjectInBackground rather than findObjectsinBackground.
Try the following:
var query = PFUser.query()!
query.whereKey("email", equalTo:userNameObject)
query.getFirstObjectInBackground { newUser, error in
if error == nil {
println(newUser)
var userVariable = newUser.objectId as String
}
}
I find only in the docs how the query can look like to select data.
As far as I see, there is only one way to collect 1 or many results:
var query = PFQuery(className:"GameScore")
query.whereKey("playerName", equalTo:"Sean Plott")
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in
if error == nil {
// The find succeeded.
NSLog("Successfully retrieved \(objects.count) scores.")
// Do something with the found objects
for object in objects {
NSLog("%#", object.objectId)
}
} else {
// Log details of the failure
NSLog("Error: %# %#", error, error.userInfo!)
}
}
What I cant figure out (as I am a beginner!) is how to access the object data. Lets say I have the fields "name", how can I get it? What is the right syntax? Especially if I have more than 1 result?
For just one result I would do:
var name = object["name"] as String
myArray.append(name)
Even that can't be right? To use "var xx = xx" within the loop?
And what do I do when I have more than one result?
Other thought:
Declaring the var name: String! before I do the query and then:
name = object["name"] as String
self.myArray.append(name)
Returns the error: Immutable vaue of type [String] only has mutating members named 'append'
What would be the correct way to "work" with the data the query returns?
Another question: as those querys are async, they finished later and the method is "done" much more earlier, this way my array with names is empty when the view is shown and I receive the data at a later stage. What is the best practice here to have all data available before the view is delivered to the device?
Thanks so much!!
You can use objectForKey on your object. So instead of using var name = object["name"] as String you can use:
for object in objects {
var name = object.valueForKey("name") as String
}
But the other parts are absolutely fine. You can create an array somewhere in you code and then add the objects to it. to do that, you can loop through your objects and than add the objects to your array. Like that:
if error == nil {
// The find succeeded.
NSLog("Successfully retrieved \(objects.count) scores.")
// Do something with the found objects
for object in objects {
var name = object["name"] as String
myArray.append(name)
}
}
Because you can reuse the var name because every loop-element will be filled into the variable name and will erase the last value. But the array will get the new value appended. For example:
First loop. The value at the first index of your objects gets loaded into the object. For example with the value "John".
variable name's value is now the value of the object["name"] of the current loop. So name has the value John
Now you add the value to your array.
The second loop starts and the second element gets loaded inside object which now has the string Michael.
The Variable name's new value is now the value of object. So name's value is now Michael
and so on.