I am using this code here:
override func viewDidAppear(animated: Bool) {
let predicate = NSPredicate(format: "username != '"+userName+"'")
var query = PFQuery(className: "_User", predicate: predicate)
do {
var objects = try query.findObjects()
for object in objects {
**self.resultsUsernameArray.append(object.username!!)**
self.resultsProfileNameArray.append(object["profileName"] as! String)
}
} catch _ {
//Error handling, if needed
}
}
The line bolded gives me the error 'The value of PFObject has no member username'. Is there something am I missing here?
Thanks, Brock.
self.resultsUsernameArray.append(object["username"] as! String)
or try:
self.resultsUsernameArray.append(object.objectForKey("username") as! String)
Related
I am developing core data in my application.
I want to fetch name attribute from the core data.
class ViewController: UIViewController {
#IBOutlet weak var saveDataBtn:UIButton!
#IBOutlet weak var dataTxtField:UITextField!
#IBOutlet weak var dataLbl:UILabel!
var tasks: [Task] = []
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
#IBAction func saveDataBtnPressed(_sender : UIButton){
print("Save Data.")
let task = Task(context: context)
task.name = dataTxtField.text
(UIApplication.shared.delegate as! AppDelegate).saveContext()
getData()
}
func getData(){
do{
tasks = try context.fetch(Task.fetchRequest())
}catch{
print("Fetching Failed")
}
}
How can i get it?
Thanks,
In Swift 4, you can access the property directly.
do {
let tasks = try context.fetch(request)
for task in tasks {
print(task.name)
}
} catch let error {
print(error.localizedDescription)
}
UPDATED - How to delete and update an instance of an Entity.
Here are some ideas to organize the code to deal with the updating and deleting.
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
extension Task {
// to get an instance with specific name
class func instance(with name: String) -> Task? {
let request = Task.fetchRequest()
// create an NSPredicate to get the instance you want to make change
let predicate = NSPredicate(format: "name = %#", name)
request.predicate = predicate
do {
let tasks = try context.fetch(request)
return tasks.first
} catch let error {
print(error.localizedDescription)
return nil
}
}
// to update an instance with specific name
func updateName(with name: String) {
self.name = name
(UIApplication.shared.delegate as! AppDelegate).saveContext()
}
// to delete an instance
func delete() {
context.delete(self)
(UIApplication.shared.delegate as! AppDelegate).saveContext()
}
}
func howItWorks() {
guard let task = Task.instance(with: "a task's name") else { return }
task.updateName(with: "the new name")
task.delete()
}
In Swift 4.1 and 5. We will use NSPredicate to specify our required condition. NSFetchRequest has a property predicate will set our predicate here as follow.
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
let predicate = NSPredicate(format: "username = %#", argumentArray: ["John"]) // Specify your condition here
// Or for integer value
// let predicate = NSPredicate(format: "age > %d", argumentArray: [10])
fetch.predicate = predicate
do {
let result = try context.fetch(fetch)
for data in result as! [NSManagedObject] {
print(data.value(forKey: "username") as! String)
print(data.value(forKey: "password") as! String)
print(data.value(forKey: "age") as! String)
}
} catch {
print("Failed")
}
self.messageFromId.removeAll()
self.messageFrom.removeAll()
self.taskTitle.removeAll()
self.message.removeAll()
self.taskId.removeAll()
self.messageId.removeAll()
self.messageType.removeAll()
if PFUser.current()?.objectId! != nil {
let query = PFQuery(className: "Message")
query.addDescendingOrder("createdAt")
query.limit = 10
cur = PFUser.current()!.objectId!
query.whereKey("messageTo", equalTo: cur!)
query.findObjectsInBackground(block: { (objects, error) in
if let posts = objects{
for object in posts {
if let post = object as? PFObject {
let query2 = PFUser.query()
query2?.whereKey("objectId", equalTo: post["messageFrom"] as! String)
query2?.findObjectsInBackground(block: { (objects, error) in
if let posts = objects{
for object in posts {
if let post2 = object as? PFObject {
if post2["handle"] as! String == "new$!" {
self.messageFromId.append(post["messageFrom"] as! String)
self.messageFrom.append(post["messageFrom"] as! String)
self.taskTitle.append(post["taskTitle"] as! String)
self.message.append(post["message"] as! String)
self.taskId.append(post["taskId"] as! String)
self.messageId.append(post.objectId!)
self.messageType.append(post["messageType"] as! String)
} else {
self.messageFromId.append(post["messageFrom"] as! String)
self.messageFrom.append(post2["handle"] as! String)
self.taskTitle.append(post["taskTitle"] as! String)
self.message.append(post["message"] as! String)
self.taskId.append(post["taskId"] as! String)
self.messageId.append(post.objectId!)
self.messageType.append(post["messageType"] as! String)
}
}
}
}
self.tableView.reloadData()
self.refresher.endRefreshing()
})
}
}
}
})
}
Results seems to come back in a random order, not sure why ? Am I doing the query within the query correctly ?
I did add : query.addDescendingOrder("createdAt") at the beginning of the query. It's not working
Try using: query.order(byDescending: "createdAt") instead.
I keep getting this error when trying to update a PFObject '[Error]: No results matched the query. (Code: 101, Version: 1.12.0)' here is my code:
let userQuery = PFQuery(className: "User")
userQuery.getObjectInBackgroundWithId("cE3DE48Fa9") {
(userQueryObject: PFObject?, error: NSError?) -> Void in
if error != nil {
print(error)
}
else if let userQueryObject = userQueryObject {
userQueryObject["House_Motto"] = self.campaignMottoTextBox.text
userQueryObject.saveInBackground()
} }
What do I do?
Here is my new code:
currentUser!.setObject(self.campaignMottoTextBox.text!, forKey: "House_Motto")
Here is an example of how to use PFUser.query() to query the user class in parse, note my example uses findObjectsInBackgroundWithBlock(), rather than getObjectsInBackgroundWithId()
var userData1 = [String]()
var userData2 = [Double]()
var allUsers = [PFUser]()
func fetchUserData() {
let userQuery: PFQuery = PFUser.query()!
userQuery.orderByAscending("username")
userQuery.whereKey("username", notEqualTo: (currentUser?.username)!)
userQuery.findObjectsInBackgroundWithBlock({
(users, error) -> Void in
var userData = users!
if error == nil {
if userData.count >= 1 {
for i in 0...users!.count-1 {
self.userData1.append(userData[i].valueForKey("columnNameInParse1") as! String)
self.startTimes.append(userData[i].valueForKey("ColumnNameInParse2") as! Double)
}
}
self.allUsers = users as! [PFUser]
self.tableView.reloadData()
} else {
print(error)
}
})
}
and in order to update a value for a given user you will do...
func updateObjectInParse(){
currentUser?.setObject(campaignMottoText.text, forKey: "columnNameInParse")
currentUser?.saveInBackground()
}
where "columnNameInParse" is the name of the column for the object of which you want to update in parse. This is case sensitive. And currentUser is the PFUser.currentUser
func getParse (className:String,key:String,dataName:AnyObject) -> (String)
{
var result = String()
var query = PFQuery(className: className)
query.whereKey(key, equalTo: dataName)
query.findObjectsInBackgroundWithBlock{
(objects, error) -> Void in
if error == nil {
println("Found")
if let objects = objects as? [PFObject] {
for object in objects {
result = object[key] as! String
}
}
} else {
println("Error \(error) \(error!.userInfo!)")
}
}
return result
}
This is my function that can getting data from my class in parse database. I want to return that data in String but it returned nothing when I try to printed it.
Thank you for every comments.
You are using an asynchronous call. You need to use findObjects(), but this will stay on the main thread. Why do you need to return a string? You could set a variable from within the completion block that could update a label on your view or something like that.
Edit: Since you are trying to set a label, you don't need to return the string, you should just set the label from within your completion block. This would modify you're given code as follows:
func getParse (className:String,key:String,dataName:AnyObject)
{
var result = String()
var query = PFQuery(className: className)
query.whereKey(key, equalTo: dataName)
query.findObjectsInBackgroundWithBlock{
(objects, error) -> Void in
if error == nil {
println("Found")
if let objects = objects as? [PFObject] {
for object in objects {
// result = object[key] as! String
self.textLabel.text = result // NEW CODE HERE
}
}
} else {
println("Error \(error) \(error!.userInfo!)")
}
}
}
func retrieveMessages() {
var query:PFQuery = PFQuery(className: "Message")
//Call findobjectsinbackground
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error:NSError?) -> Void in
self.messagesArray = [String]()
for messageObject in objects { <<<<<<<<<<<<<<<<< error
let messageText:String? = (messageObject as PFObject)["Text"] as? String
if messageText != nil {
self.messagesArray.append(messageText!)
}
}
self.messageTableView.reloadData()
}
}
From this code an error occurs saying: [AnyObject]? does not have a member named 'Generator'. Is there a way how to correct this?
Your objects array is declared as an Optional : objects:[AnyObject]?
So you need to unwrap it before looping over it:
for messageObject in objects! {
// do stuff
}
And since objects can be nil, better do this:
if let myObjects = objects {
for messageObject in myObjects {
// do stuff
}
}
That's because it is an optional array. Simply wrap it around if let and you'll be fine.
In playground:
func retrieveMessages(objects:[AnyObject]?) {
var messagesArray = [String]()
if let objs = objects {
for messageObject in objs {
let messageText:String? = "test"
if messageText != nil {
messagesArray.append(messageText!)
}
}
}
}
In your case, the complete code would be:
func retrieveMessages() {
var query:PFQuery = PFQuery(className: "Message")
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error:NSError?) -> Void in
self.messagesArray = [String]()
if let objs = objects {
for messageObject in objs {
let messageText:String? = (messageObject as PFObject)["Text"] as? String
if messageText != nil {
self.messagesArray.append(messageText!)
}
}
}
self.messageTableView.reloadData()
}
}
Since your objects Array is of [AnyObject]?, before using them you need to do below step.
if let myObjects = objects as? [PFObject] {
//Do the things...
}
[AnyObject]? it´s an optional array.
You must unwrap it before using it.
if let objects = objects
{
for messageObject in objects
{
....
}
}