mark this question as solved quesstion apples ios parse query xcode for text and images by the user app

Hello



I'm trying to create my first app using xcode.


This fails I on the parse query for text and images.


How should I write the query, that the images and text from the user registered in the app is displayed.


That I cobbled together and work not just as planned.


override func viewDidLoad() {
        super.viewDidLoad()
        let query = PFQuery(className: "Post")
        query.findObjectsInBackground(block: { (object, error) in
            if error != nil{
                print(error)
            }else{
                if let posts = object {
                    for post in posts {
                    query.whereKey("imageFile", equalTo: self.imageFile)
                    query.whereKey("message", equalTo: self.comments)
                    query.getObjectInBackground(withId: "post")
                     
                        self.comments.append(post["message"] as! String)
                        self.imageFile.append(post["imageFile"] as! PFFile)
                        self.tableView.reloadData()
                }
            }
         
                }
         
    })
}



Thank you for your help.



Best regards Daniel

When you say "it fails", can you describe more precisely?


- Compilation error ?

- Execution crash ?

- Not getting expected result ? If so, what do you get.


What do you expect from the queries lines 10 to 12 ? Where do you store results ?


You should probably do something more like this instead:


let image = object.valueForKey("imageFile") as! PFFile
self.imageFile.addObject(image)


Could you please also change the title of the post : AVOID USING UPPERCASE, and probably delete the first line. Thanks

Thanks for your answer.


The app Execution crash.

I've never done this and something from the Internet to seed I tinkered.


I would like to do the query text and the image of the user logged-on is displayed.

I've got two Class. 1st post and 1 user. The users are stored in the user and post the relevant texts and images.


Save of texts and images work. But that get no. I don't know how I have to write the query.


import UIKit
import Parse
class FeedTableViewController: UITableViewController {
    var users = [String: String]()
    var comments = [String]()
    var imageFile = [PFFile]()
    var usernames = [String]()
   
   
    /
    @IBAction func logoutUser(_ sender: Any) {
       
        PFUser.logOut()
       
        performSegue(withIdentifier: "logoutSegue", sender: self)
       
        return
        }
       
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
       
        if segue.identifier == "logoutSegue" {
            PFUser.logOut()
            print("logout")
        }
       
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        let query = PFQuery(className: "Post")
        query.findObjectsInBackground(block: { (object, error) in
            if error != nil{
                print(error)
            }else{
                if let posts = object {
                    for post in posts {
                    query.whereKey("imageFile", equalTo: self.imageFile)
                    query.whereKey("message", equalTo: self.comments)
                    query.getObjectInBackground(withId: "post")
                       
                        self.comments.append(post["message"] as! String)
                        self.imageFile.append(post["imageFile"] as! PFFile)
                        self.tableView.reloadData()
                }
            }
           
                }
           
    })
}
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        /
    }
    / 
    override func numberOfSections(in tableView: UITableView) -> Int {
        /
        return comments.count
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        /
        return 1
    }
   
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! FeedTableViewCell
       
        imageFile[indexPath.row].getDataInBackground{ (data, error) in
            if let imageData = data {
                if let imageToDysplay = UIImage(data: imageData){
                    cell.postedImage.image = imageToDysplay
                }
            }
        }
        /
        cell.comment.text = comments[indexPath.row]
        return cell
               
       
    }

Where (which line?) does it crash ?

What is the crash log ?


I don't know Parse syntax, but there is something I don't understand in your code:


                    query.whereKey("imageFile", equalTo: self.imageFile)
                    query.whereKey("message", equalTo: self.comments)
                    query.getObjectInBackground(withId: "post")

query.whereKey changes the query,

"Add a constraint to the query that requires a particular key’s object to be equal to the provided object."

After the second whereKey, I think the result is empty


What are you trying to do here ? Do you know how PFQuery works (otherwise you shopuld read the doc in detail).


In addition, changing the query inside the completion block of query.findObjectsInBackground is curious.

If I had to do it, I would try to replace lines 38 to 43 by:


if let image = object.valueForKey("imageFile") as? PFFile {
     self.imageFile.addObject(image)
} else {
     print("Error reading imageFile")
}
if let message = object.valueForKey("message") as? String {
     self.comments.addObject(message)
} else {
     print("Error reading message")
}

This is specified

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot do a comparison query for type: Swift._EmptyArrayStorage'


I know the line not where I can see this?


I've commented out

                    query.whereKey("imageFile", equalTo: self.imageFile)
                    query.whereKey("message", equalTo: self.comments)
                    query.getObjectInBackground(withId: "post")

Now I'm getting the pictures and texts displayed :-). But all famiy user.

Thank you very much, I am very pleased about this progress


You know how I can filter it to display only the images and texts from the user logged-on?

You refer only to the Post class, hence there is no filtering on User.

Maybe you could test if the image or message belong to the user, by reading username in Post class ?


But there is not enough information to tell you how to do it exactly.


Did you try inserting the code of my previous post, in place of lines 38-43 ? What is the result ?


if let image = object.valueForKey("imageFile") as? PFFile {
     self.imageFile.addObject(image)
} else {
     print("Error reading imageFile")
}
if let message = object.valueForKey("message") as? String {
     self.comments.addObject(message)
} else {
     print("Error reading message")
}

I get this message

Value of type '[PFObject]?' has no member 'valueForKey'


Maybe you could test if the image or message belong to the user, by reading username in Post class ?

I've done this. This has unfortunately no effect

I get this message

Value of type '[PFObject]?' has no member 'valueForKey'


On which line ?

I suppose it is in

if let image = object.valueForKey("imageFile") as? PFFile {
     self.imageFile.addObject(image)

When you report an error, please show the code you test and tell the eaxcvt line where the error occurs.


It's in fact normal, as object is of type [PFObject]?


So should be

if let image = post.valueForKey("imageFile") as? PFFile {
     self.imageFile.addObject(image)

I have a built in it again, this has been but no verenderung and no output. With or without

if let image = object.valueForKey("imageFile") as? PFFile {
     self.imageFile.addObject(image)
} else {
     print("Error reading imageFile")
}
if let message = object.valueForKey("message") as? String {
     self.comments.addObject(message)
} else {
     print("Error reading message")
}

could any difference notice.


My current stand is

So it gives no output, but also no crash

override func viewDidLoad() {
        super.viewDidLoad()
    
        let query = PFQuery(className: "Post")
        var currentUser = PFUser.current()?.username
        query.whereKey("username",equalTo:"currentUser")
        query.findObjectsInBackground(block: { (post, error) in
        
              if let posts = post {
                for post in posts {
    
                        self.comments.append(post["message"] as! String)
                        self.imageFile.append(post["imageFile"] as! PFFile)
                        self.tableView.reloadData()
                
                }
            }
    })
}



So the images and texts are displayed but independent of the user


override func viewDidLoad() {
        super.viewDidLoad()
      
        let query = PFQuery(className: "Post")
        /
        /
        query.findObjectsInBackground(block: { (post, error) in
          
              if let posts = post {
                for post in posts {
      
                        self.comments.append(post["message"] as! String)
                        self.imageFile.append(post["imageFile"] as! PFFile)
                        self.tableView.reloadData()
                  
                }
            }
    })
}

First part of your message :

if let image = object.valueForKey("imageFile") as? PFFile {

As I wrote in my previous post, should not use object.valueForKey, but post.valueForKey


Second part :

        let query = PFQuery(className: "Post")
        var currentUser = PFUser.current()?.username
        query.whereKey("username",equalTo:"currentUser")
        query.findObjectsInBackground(block: { (post, error) in


Does your class "Post" have a field named username ? Otherwise, no match can be found by query.whereKey("username",equalTo:"currentUser")

It would help if you showed the structure of this class


Otherwise, that is probably the right way to do it.

Note: I find reusing the same identifier (post) not a good practice, because when you refer to post, you don't know what you speak about (even if here, scope visibility makes it work)

you'd better write

              if let posts = post {
                for aPost in posts {


Part 3

You could also add a test on aPost with a where clause ; theTestToDo is comparing currentUser with the right property of aPost


override func viewDidLoad() {
        super.viewDidLoad()
   
        let query = PFQuery(className: "Post")
        let currentUser = PFUser.current()?.username

        query.findObjectsInBackground(block: { (post, error) in
              if let posts = post {
                for aPost in posts where theTestToDo {

The class "Post" had the columns:

objectId, createdAt, updateAt, ACL, message, imageFile, userId and username, in the username the mail address is stored.



I will implement your suggestions after work and write you.



Many Thanks

For testing purpose, you could start with the following:


override func viewDidLoad() {
        super.viewDidLoad()

        let query = PFQuery(className: "Post")
        let currentUser = PFUser.current()?.username

        query.findObjectsInBackground(block: { (post, error) in
              if let posts = post {
                for aPost in posts  {
                    print(aPost)
                    if aPost.username == currentUser {
                       self.comments.append(post["message"] as! String)
                       self.imageFile.append(post["imageFile"] as! PFFile)
                        // I would do it later: self.tableView.reloadData()
                   } else {
                         print("No match between ", aPost.username, " and ",  currentUser)
                    }
               }
               self.tableView.reloadData()     // At the end of the loop


If it works OK, then simplify as:


override func viewDidLoad() {
        super.viewDidLoad()

        let query = PFQuery(className: "Post")
        let currentUser = PFUser.current()?.username

        query.findObjectsInBackground(block: { (post, error) in
              if let posts = post {
                  for aPost in posts where aPost.username == currentUser {
                       self.comments.append(post["message"] as! String)
                       self.imageFile.append(post["imageFile"] as! PFFile)
                 }
               self.tableView.reloadData()     // At the end of the loop

Thank you for your help. Sorry that I write now, wanted to not write without results. I have long tried the if loop to the running, this has so unfortunately not useful. This is my result


I had to change the code so that reflected something worked

override func viewDidLoad() {
        super.viewDidLoad()
        let query = PFUser.query()
        query?.whereKey("userId", equalTo: PFUser.current()?.username)
        query?.findObjectsInBackground(block: { (objects, error) in
        let query = PFQuery(className: "Post")
            if let posts = objects {
                for post in posts  {
                    print(post)
                    self.imageFile.append(post["imageFile"] as! PFFile)
                    self.comments.append(post["message"] as! String)
            }
    
            }
    })
}


The result is

row 10. and 11. the app, with the message: Fatal error: Unexpectedly found nil while unwrapping an Optional value


In the Output:

Unknown class UINacvigationController in Interface Builder file.

<PFUser: 0x6000002e2680, objectId: VBTOwnVeED, localId: (null)> {

ACL = "<PFACL: 0x60000043d6e0>";

username = "test@test.ch";

}

(lldb)

I'm surprised you get the message


Unknown class UINacvigationController in Interface Builder file


Seems you have mispelled the type of your class as UINacvigationController instead of UINavigationController (an extra "c" in name)

Thanks for the clue, I missed this

I am to the start back and have just this query works made.

the issue

<Post: 0x6000002a1e60, objectId: rPpAAPGGmq, localId: (null)> {

imageFile = "<PFFile: 0x600000646cf0>";

message = "Test text zum 123";

userId = VBTOwnVeED;

username = "test@test.ch";

}


She query

override func viewDidLoad() {
        super.viewDidLoad()
   
        let query = PFQuery(className: "Post")
   
        query.getObjectInBackground(withId: "rPpAAPGGmq") { (object, error) in
       
            if let post = object {
                print(post)
            }
       
        }
    }

So the username is " test@test.ch"with leading blanks.


Is it the same in currentUser via

let currentUser = PFUser.current()?.username

mark this question as solved quesstion apples ios parse query xcode for text and images by the user app
 
 
Q