Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Ribbit/swift clone : loading followed user post

Hello

I' m trying to make an instagram clone with swift, based on the Ribbit tuto. People can share photos and follow other users etc etc. I made a PFRelation between users using Parse. What i would like to do now, is to show in my WalltableViewController, only the followed users post.

I made a function to load all the post in a NSMutable array called timeLineData.

I ve even made a function to get the followed users ina NSMutable array called followedFriends..

But i don't succeed in filtering the loading post function with followedFriends. I have this error : Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot do a comparison query for type: __NSArrayM'

Here is my code :

     import UIKit
     import QuartzCore

    class WallTableViewController: UITableViewController, UINavigationControllerDelegate {

   @IBOutlet var posterAvatar: UIImageView!

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return UIStatusBarStyle.LightContent
}


var timeLineData:NSMutableArray = NSMutableArray ()
var followedFriends:NSMutableArray = NSMutableArray ()

func loadUser () {

    followedFriends.removeAllObjects()
    var friendsRelation: AnyObject! = PFUser.currentUser().objectForKey("KfriendsRelation")


    var findUser : PFQuery = friendsRelation.query()


    findUser.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!, error:NSError!) -> Void in
        if !(error != nil) {
            // The find succeeded.
            println("succesfull load Users")
            // Do something with the found objects
            for object  in objects  {
                self.followedFriends.addObject(object)
                println("users added to userlist")

                for item in self.followedFriends {
                    println(item)                    }
            }
            self.tableView.reloadData()
        } else {
            // Log details of the failure
            println("error loadind user ")

        }

    }
}


func loadPost () {

    timeLineData.removeAllObjects()

    let currentUser = PFUser.currentUser()

        var findPost:PFQuery = PFQuery(className: "UserPost")


    findPost.whereKey("from", equalTo: followedFriends )


        findPost.orderByDescending("createdAt")


        findPost.findObjectsInBackgroundWithBlock {
            (objects: [AnyObject]! , error: NSError!) -> Void in
            if !(error != nil) {
                // The find succeeded.
                println("current user post finded")
                // Do something with the found objects
                for object  in objects  {
                    self.timeLineData.addObject(object)
                }
                self.tableView.reloadData()
            } else {
                // Log details of the failure
                println("error loadind user post")
            }


        }

    }


override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

 override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return timeLineData.count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell:WallTableViewCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as WallTableViewCell

    let userPost:PFObject = self.timeLineData.objectAtIndex(indexPath.row) as PFObject

    //define the username

    var findUser:PFQuery = PFUser.query()
    findUser.whereKey("objectId", equalTo: userPost.objectForKey("from").objectId)

    findUser.findObjectsInBackgroundWithBlock{
        (objects:[AnyObject]!, error:NSError!) -> Void in

        if !(error != nil) {
            if let user:PFUser = (objects as NSArray).lastObject as? PFUser {
                cell.usernameLabel.text = user.username

                // define avatar poster

                if let avatarImage:PFFile = user["profileImage"] as? PFFile {
                    avatarImage.getDataInBackgroundWithBlock{(imageData:NSData!, error:NSError!)-> Void in

                        if !(error != nil) {

                            let image:UIImage = UIImage(data: imageData)


                            cell.posterAvatar.image = image as UIImage
                            cell.posterAvatar.layer.cornerRadius = 24
                            cell.posterAvatar.clipsToBounds = true

                        }

                    }
                }
                else {
                    cell.posterAvatar.image = UIImage(named: "Avatar-1")
                    cell.posterAvatar.layer.cornerRadius = 24
                    cell.posterAvatar.clipsToBounds = true
                }
            }

        }

    }

    //define the imagepost

    let imagesPost:PFFile = userPost["imageFile"] as PFFile


    imagesPost.getDataInBackgroundWithBlock{(imageData:NSData!, error:NSError!)-> Void in

        if !(error != nil) {

            let image:UIImage = UIImage(data: imageData)

            cell.imagePosted.image = image as UIImage


        }
        else {
            println("error")
        }
    }


    return cell
}


override func viewDidAppear(animated: Bool) {
    var currentUser = PFUser.currentUser()
    if (currentUser != nil) {
        println("User allready logued")
    }

    else {
        // Show the signup or login screen

        self.performSegueWithIdentifier("goToLogIn", sender: self)
    }

}


override func viewWillAppear(animated: Bool) {
    self.tableView.separatorColor = UIColor.whiteColor()

    tabBarController?.tabBar.tintColor = UIColor.whiteColor()
    self.loadUser()
    self.loadPost()
    self.tableView.reloadData()

}

}

2 Answers

you cant pass in an array as a key to compare to. you may be able to use another query method though with an array.

one thing you could do is you could use a query to first get the users friends, then use the results of that query to find all of the posts of those users:

//query for the friends of the user
var friendsRelation: AnyObject! = PFUser.currentUser().objectForKey("KfriendsRelation")
var findFriends : PFQuery = friendsRelation.query()

//using the friends from the query above, we find all the posts of the friends of the current user
var findPosts:PFQuery = PFQuery(className: "UserPost")
findPosts.whereKey("from", matchesQuery:findFriends)
findPost.orderByDescending("createdAt")

//run the query
 findPosts.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!, error:NSError!) -> Void in
        if !(error != nil) {
            //found posts

            self.tableView.reloadData()
        } else {
            // Log details of the failure
            println("error loadind posts ")

        }

    }

the above basically combines finding the users friends, and then getting the users post into one simply query.

Thank you Stone it work perfectly ! You saved my life another time...;)