PFQuery found a nonexistent object - Swift - ios

I'm trying to query a nonexistent object like this code bellow, but always "Mike" is found. What could be wrong? Everything is working great (Save, Delete, Update and Query without error recognition).
var query = PFQuery(className:"Restaurant")
query.whereKey("clientname", equalTo:"Mike")
query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if (error == nil) {
print ("Found")
}
else {
print ("Not Found")
}
}

Try checking (debugging) what "objects" actually is. I think you will see that it is an empty array, meaning it did NOT find Mike.
An empty array of results is not a query error. The query succeeds, but finds no objects. So not getting an error does not mean "Found". It just means there was no error.

Related

Running Parse code after another has finished execution

I'm trying to query a class of objects with specific ID's to delete. When I run it however, I get an error for "This query has an outstanding network connection. You have to wait until it's done". I assume this is because I'm trying to delete an object while I'm still accessing it.
I've provided the deletion code in the closure because I'm assuming the closure statements only execute after the function call finishes, yet it's still giving me the error. I've also tried using DispatchGroups because it does seem like a concurrency issue, but I'm not too familiar with their usage yet. Here's my code:
let idList = [...] // Some list of ID's I would like to remove
let query = PFQuery(className: "Pictures")
for id in idList {
query.getObjectInBackground(withId: id) { (object: PFObject?, error:
Error?) in
if error == nil {
img?.deleteInBackground() { (success, error: Error?) ...
}
}
I'm expecting each object associated with an ID in my original IdList to be deleted from the Parse backend. However, it seems that getObjectInbackground() and deleteInBackground() are clashing. If anyone could provide some advice, that would be wonderful!
You can try
var idList = [...]
func delete(_ id:Int) {
query.getObjectInBackground(withId: id) { (object: PFObject?, error: Error?) in
if error == nil {
img?.deleteInBackground() { (success, error: Error?) ...
}
idList = Array(idList.dropFirst())
if !idList.isEmpty {
delete(idList.first!)
}
}
}
Initially call it like
delete(idList.first!)

Parse query on array of pointers only retrieving first object

In the code below, self.arrayOfLikers is an array of Pointers to Parse User Objects. Which looks like this on Parse:
var query = PFQuery(className: "Item")
query.includeKey("likedBy")
query.getObjectInBackgroundWithId(theObjectIdOfTheItem!) { (returnedItem, error) in
if error != nil {
print(error)
}
else {
returnedItem?.fetchInBackgroundWithBlock({ (fetchedReturnedItem, error) in
if error != nil {
print(error)
}
else {
dispatch_async(dispatch_get_main_queue(),{
self.arrayOfLikers = fetchedReturnedItem!["likedBy"] as! [PFUser]
print("about to print the arrayOfLikers")
print(self.arrayOfLikers)
self.tableView.reloadData()
})
}
})
}
}
When I print my self.arrayOfLikers I can see that the first index contains a correctly retrieved PFUser object. Below is a print statement from Xcode:
In another viewController, I am storing these pointers when the user taps the "like" button. This is how I am storing those pointers:
Creation of the userPointer:
let userPointer = PFObject(outDataWithClassName: "User", objectId: user?.objectId)
(oddly, the Parse docs use withoutDataWithClassName, but when I put this in, Xcode keeps making me change it outDataWithClassName, and it compiles, so I guess this is correct?)
Storing the userPointer: (please note, theItemObject is an object set by a previous VC):
theItemObject!.addObject(userPointer, forKey: "likedBy")
Consequently, Parse via Xcode gives me this error:
2016-03-30 23:38:47.749 Trashly[5482:1512409] [Error]: object not found for get (Code: 101, Version: 1.12.0)
Optional(Error Domain=Parse Code=101 "object not found for get" UserInfo={code=101, temporary=0, error=object not found for get, NSLocalizedDescription=object not found for get})
Any ideas why my query is not getting any user objects but the first one?

Why does the "objects: [PFObject]?" parameter of Parse's findObjectsInBackgroundWithBlock function return nil?

This is for an existing class on Parse called "HellsKitchen" and I have tried others, but always receive nil on objects.
let query = PFQuery(className: "HellsKitchen")
query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
print("got em: \(objects)")
} else {
print("error: \(error!.userInfo)")
}
}
All of the other posts about this refer to the block closure when they had objects as [AnyObject]? but it has since changed sometime in late 2015 and I no longer need to cast it as PFObject as all the answers say.
I have tried adding App Transport Security Settings > Allow Arbitrary Loads = YES to my Info.plist to no avail.
I get no error from the block either. It passes into the if statement because error == nil and prints "got em: nil".
How can I get my objects?

Searching Parse using pointer returns error "pointer field needs a pointer value"

I'm trying to do a query by selectedBook (this is a string of selectedBook's objectID). However, I'm getting this error: "[Error]: pointer field book needs a pointer value (Code: 102, Version: 1.8.2)." I believe I have to do the query with the actual book object rather than the objectID, how can I go about doing this? Thanks in advance!!
var query = PFQuery(className:"UserTags")
query.whereKey("book", equalTo:selectedBook)
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error:NSError?) -> Void in
if error == nil {
// The find succeeded.
print("Successfully retrieved \(objects!.count) tags.")
// Do something with the found objects
if let objects = objects as? [PFObject] {
for object in objects {
print(object.objectId)
}
}
} else {
// Log details of the failure
print("Error: \(error!)")
}
Figured it out. Here is the code in case someone else runs into this:
let pointer = PFObject(withoutDataWithClassName:"Book", objectId: booksObjectID)
var query = PFQuery(className: "UserTags")
query.whereKey("book", equalTo: pointer)
query.includeKey("book")
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error:NSError?) -> Void in
for object in objects! {
self.userTags.addObject(object)
}
}
From documentation:
InvalidQuery - 102 - Error code indicating you tried to query with a
datatype that doesn't support it, like exact matching an array or
object.
The error description tells you a lot. This kind of querying does not support queuing by object (in your case, book). You have to use a datatype that is supported - for example query by book ID or name which are more primitive data types.

Parse: deleting object value in column using Swift

I've used Parse successfully in other apps before but never used the delete function. I'm trying to delete a value ( an alphabetical letter) in a column (column title is 'letter') associated with a user in Parse. I'm using Swift. The code is finding the correct value as evident via a println in the deletion code, but nothing is happening after the remove and save functions are executed. The value is still there in the column. And I'm not getting any Parse errors. The code is below. Any help, as always, will be greatly appreciated.
var query = PFQuery(className: "game")
query.whereKey("player", equalTo:PFUser.currentUser())
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in
if !(error != nil) {
for object in objects {
var myLetter = object["letter"]! as String
println("The object for key letter is \(myLetter)") //This prints the correct letter in the current user's Letter column
PFUser.currentUser().removeObjectForKey("letter")
PFUser.currentUser().saveInBackgroundWithBlock{
(success: Bool, error: NSError!) -> Void in
if (success) {
// The object has been saved.
println("success")
} else {
// There was a problem, check error.description
println(error)
}
}
}
}
}
I think the issue is that you are creating a new Parse query and deleting it locally as opposed to retrieving the item and then deleting it. So, retrieve the item you want to delete and then call the deleteInBackground method.

Resources