Retrieve object from Parse with Swift - ios

I'm developing a simple iOS application. It's a simple quiz app. I'm using Parse to store my questions, answers etc. I've read all the documentation and cannot find why this code to retrieve an object is not working.
var query = PFQuery(className: "Test_Questions")
query.getObjectInBackgroundWithId("cJzv2JdMej", block: {
(questionObject: PFObject?, error: NSError?) -> Void in
let thisQuestion = questionObject["question"] as! String
//Error here: AnyObject is not convertible to String
})
Your help would be much appreciated!
Console Output:
Optional(What statement must come before an else statement?)

You should try this instead:
var query = PFQuery(className: "Test_Questions")
query.getObjectInBackgroundWithId("cJzv2JdMej", block: {
(questionObject: PFObject?, error: NSError?) -> Void in
if error == nil {
println(questionObject)
//if there's info in the console you know the object was retrieved
let thisQuestion = questionObject["question"] as? String
} else {
println("Error occurred retrieving object")
}
})
If that doesn't work you can also try let thisQuestion = questionObject.valueForKey("question"). Also make sure that Parse is actually returning an object by adding a print statement such as println(questionObject) after it has been retrieved so that you know Parse is returning an object.

Got it!
var query = PFQuery(className: "Test_Questions")
query.getObjectInBackgroundWithId("cJzv2JdMej", block: {
(questionObject: PFObject?, error: NSError?) -> Void in
let thisQuestion: AnyObject! = questionObject!.valueForKey("question")
self.question.text = thisQuestion as? String
})

Related

'PFObject' is not a subtype of 'Post' - Swift Error

So I'm fairly new to Swift and I've been trying to follow along with a tutorial I found on Youtube. Its going well, however, I've ran into an error that I can't seem to find any solution online. So I keep getting this error: "'PFObject' is not a subtype of 'Post'" from the following code:
var posts : [Post] = []
var postDates = [String]()
func loadData() {
var query = PFQuery(className: "Post")
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock {(post: [PFObject]?, error: NSError?)-> Void in
if (error == nil) {
if let posts = posts as? [PFObject] {
for post in posts {
self.postDates.append(posts["createdAt"] as! String)
}
self.tableView.reloadData()
}
} else {
// is an error
}
}
}
The error occurs at: if let posts = posts as? [PFObject]
This is the video I've been following along to: https://www.youtube.com/watch?v=L3VQ0TE_fjU
If anyone can help explain whats going on, I'd very much appreciate it.
For those having trouble in the future, here was my solution:
query.findObjectsInBackgroundWithBlock {(posts: [AnyObject]?, error: NSError?)-> Void in

Retrieving info from Parse

I am trying to build a chat application, but I have a problem with this code:
func loadData() {
let FindTimeLineData: PFQuery = PFQuery(className: "Message")
FindTimeLineData.findObjectsInBackgroundWithBlock { (objects: [AnyObject]!, NSError) -> Void in
self.MessagesArray = [String]()
for MessageObject in objects {
let messageText: String? = (MessageObject as! PFObject) ["Text"] as? String
if messageText != nil {
self.MessagesArray.append(messageText!)
}
}
}
}
I need to retrieve data from Parse, but the .findObjectsInBackgroundWithBlock method tells me that it cannot convert a value of type AnyObject into Void in. How can I resolve this problem? Thanks in advance.
Try it like this instead:
var query = PFQuery(className: "Message")
query.findObjectsInBackgroundWithBlock {
(remoteObjects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
print("Retrieved \(remoteObjects!.count) messages from server.")
self.MessagesArray = [String]() // By convention, you should name this "messagesArray" instead, and initialize it outside this method
for messageObject in remoteObjects {
if let messageText: String? = messageObject["Text"] as? String {
self.messagesArray.append(messageText)
}
}
} else {
print("Error: \(error!) \(error!.userInfo)")
}
}
(not properly proof-read, but you should be able to get it to work from this)
For the record, there are LOTS of duplicate questions with this problem - i know, as I had the same problem after converting Parse code to Swift 2.1.
So, please do a little more research before you post a question. Often, SO even hints at you similar questions as you are typing...
As for the answer, the Parse API doesn't force you to cast the object as AnyObject anymore in the completion block of a query, so it can look just like this:
query?.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if let messages = objects {
for message in messages {
.... etc

Check if a row exists in Parse, if it does update a column in the row instead of creating a new row each time. Swift

I have a className called SearchPreferences and it is empty until the current user makes a selection. When they make a selection a new row is created in this class with the updated info. The problem is if the user goes back and makes another selection I am creating a new row again instead of just updating the column. Here is the code that is saving the info but on a new row:`
let music = PFObject(className: "SearchPreferences")
music["music"] = table_data[indexPath.row]
// music["user"] = PFUser.currentUser()!.username!
music.saveInBackgroundWithBlock{(success, error) -> Void in
if error == nil {
music.saveInBackground()
print("success")
} else {
print("error")
}
}
`
All I can find is SQL and PHP online help. I tried the code below to call objId but I don't know it as its empty so it returns the below error.
The code below returns the error
No results matched the query. (Code: 101, Version: 1.7.5)
let query = PFQuery(className:"SearchPreferences")
query.getObjectInBackgroundWithId("musicSearch") {
(searchPreference: PFObject?, error: NSError?) -> Void in
if error != nil {
if let searchPreference = searchPreference {
searchPreference["musicSearch"] = self.table_data[indexPath.row]
searchPreference.saveInBackground()
if error == nil {
query.whereKeyDoesNotExist("musicSearch")
let searchPreference = PFObject(className: "SearchPreferences")
searchPreference["musicSearch"] = self.table_data[indexPath.row]
searchPreference.saveInBackgroundWithBlock{(success, error) -> Void in
The same can be send for this attempt:
var query = PFQuery(className:"SearchPreferences")
query.getObjectInBackgroundWithId("musicSearch") {
(searchPreference: PFObject?, error: NSError?) -> Void in
if error != nil {
print(error)
} else if let searchPreference = searchPreference {
searchPreference["musicSearch"] = self.table_data[indexPath.row]
searchPreference.saveInBackground()
}
}
I am trying to figure out how to either before running the query check if it is empty and if it is carry out my initial query. Parse docs only tell you how to save to classname _User not a second classname.
Here is an example on duplicated record update from parse community, you can use the same method to apply it with your code.
let adventureQuery = PFQuery(className: “Class Name“)
adventureQuery.limit = 1000
adventureQuery.addDescendingOrder(“Column Name”)
adventureQuery.getFirstObjectInBackground { (Success, error) in
Success?.setValue(self.toolsTitleTextField.text, forKey: "toolsTitle")
Success?.setValue(self.locationTextField.text, forKey: "location")
Success?.setValue(self.dateTextField.text, forKey: "createrDate")
Success?.saveInBackground(block: { (success, error) in
if (success){
Utility.showAlert("Success!", message: "Insert SuccessFully", viewController: self)
}
else{
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "") as! ViewController
self.navigationController?.pushViewController(viewController, animated: true)
}
})
}

Issues with changing existing Parse data

I am working with Parse for the first time in my application, and everything seems to be working well with the exception of when I go to change existing data. I am simply trying to change a string value that I have stored in a column of one of my items.
This is the code I currently have:
func sendTimeToParse() {
var query = PFQuery(className: "ClassName")
query.whereKey("Name", equalTo: rideNamePassed)
query.getFirstObjectInBackgroundWithBlock {
(object: PFObject?, error: NSError?) -> Void in
if error != nil {
println("The getFirstObject request failed.")
} else {
// The find succeeded.
let object = PFObject(className: "ClassName")
object.setValue(self.timeSelected, forKey: "WaitTime")
object.saveInBackground()
println("Successfully retrieved the object.")
}
}
}
}
At the moment it just seems to create a new row of data and saves the time to that, however obviously I would like it to change the existing data in whatever row matches the name of the current record.
Anyone have any suggestions?
The problem is that you are creating a new PFObject with the line let object = PFObject(className: "ClassName") instead of using the retrieved object which is given as a parameter.
Simply delete the line let object = PFObject(className: "ClassName") and unwrap the received optional. It could look something like the following:
func sendTimeToParse() {
var query = PFQuery(className: "ClassName")
query.whereKey("Name", equalTo: rideNamePassed)
query.getFirstObjectInBackgroundWithBlock {
(object: PFObject?, error: NSError?) -> Void in
if error != nil {
println("The getFirstObject request failed.")
} else {
if let obj = object {
obj.setValue(self.timeSelected, forKey: "WaitTime")
obj.saveInBackground()
}
println("Successfully retrieved the object.")
}
}
}

PFObject can't be converted

Then i try to convert a key from PFObject to a String it gives me a error. I can't find anything on Parses website. Please help
var findProgram = PFQuery(className: "Programs")
findProgram.getObjectInBackgroundWithId(data["program"] as! String!, block: { (object: PFObject?, error) -> Void in
if error == nil {
var objects = object["name"] as! String
print(objects)
self.programUpdated.append(object?.createdAt as NSDate!)
}
})
I think this is what you're going to have to do, try this:
//explicitly giving the objects var a type of String
var objects:String = object["name"] as! String
You shouldn't get an error after that.
Good luck!
I think this will be the batter way to do that:
if let objects = object?.objectForKey("name") as? String{
print(objects)
self.programUpdated.append(objects?.createdAt as NSDate!)
}

Resources