Xcode Parse Query button Delete text and photo from a cell - ios

each cell displays the according comments and photo of the user logged-on. They are loaded with parse.
Now you want to Löschen the button deletes the photo and the comments.
Unfortunately this does not work. Wen I click on the button nothing happens
Unfortunately I understand little of swift and can't get on the solution
The query works, and the app displays the photos and Commons.The query and post code:
override func viewDidLoad() {
super.viewDidLoad()
super.viewDidLoad()
let query = PFQuery(className: "Post")
query.whereKey("username", equalTo: PFUser.current()?.username)
query.findObjectsInBackground(block: { (object, error) in
if let posts = object {
for post in posts{
print(posts)
self.comments.append(post["message"] as! String)
self.imageFile.append(post["imageFile"] as! PFFile)
self.tableView.reloadData()
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
})
}
And here of the "delete"function code that I have tried:
#IBAction func remove(_ sender: Any) {
print("Entered remove")
let query = PFQuery(className: "Post")
query.whereKey("username", equalTo: PFUser.current()?.username)
query.findObjectsInBackground(block: { (object, error) in
if let posts = object {
print(posts)
for post in posts{
print(posts)
if let message = post["message"] as? String, let image = post["imageFile"] as? PFFile {
print("message and image read", message, image)
if let messageIndex = self.comments.index(of: message), let imageIndex = self.imageFile.index(of:image) {
self.comments.remove(at: messageIndex)
self.imageFile.remove(at: imageIndex)
}
}
self.tableView.reloadData()
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
})
}
The output:
I don't get an error message and nothing is deleted.
Thank you for your help

You do not have access to your current index where and object ids.
So based on that you can remove easy.
The more easy way to implement the delete function is to have an array of objectId for your messages:
self.ids.append(post.objectId)
And when you want to delete it:
let query = PFQuery(className: "Post")
query.whereKey("objectId", equalTo: self.ids.index(of: indexPath.row))
// Make a query in background to only get the object that you want to delete
query.getFirstObjectInBackgroundWithBlock {
(object: PFObject?, error: NSError?) -> Void in
if error != nil || object == nil {
print("The getFirstObject request failed.")
} else if let object = object {
print("Successfully retrieved the object.")
object.deleteInBackground()
}
}
Having different arrays representing the same object is not really good to do. So a better way to handle you problem is have only one array for your post
When you fetch it you can do something like that:
guard let user = PFUser.current() else { return }
let query = PFQuery(className: "Post")
query.whereKey("username", equalTo: user.username)
query.findObjectsInBackground(block: { (posts, error) in
if let posts = posts {
self.posts = posts
}
})
With this way when you want to delete it in the remove function:
if indexPath.row < self.posts.count {
self.posts[indexPath.row].deleteInBackground()
}

Related

xcode parse Query button Delete photo and text from the cell

each cell displays the according comments and photo of the user logged-on. They are loaded with parse.
Now you want to Löschen the button deletes the photo and the comments.
Unfortunately this does not work. Wen I click on the button nothing happens
Unfortunately I understand little of swift and can't get on the solution
The query works, and the app displays the photos and Commons.The query and post code:
override func viewDidLoad() {
super.viewDidLoad()
super.viewDidLoad()
let query = PFQuery(className: "Post")
query.whereKey("username", equalTo: PFUser.current()?.username)
query.findObjectsInBackground(block: { (object, error) in
if let posts = object {
for post in posts{
print(posts)
self.comments.append(post["message"] as! String)
self.imageFile.append(post["imageFile"] as! PFFile)
self.tableView.reloadData()
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
})
}
And here of the "delete"function code that I have tried:
#IBAction func remove(_ sender: Any) {
let query = PFQuery(className: "Post")
query.whereKey("username", equalTo: PFUser.current()?.username)
query.findObjectsInBackground(block: { (object, error) in
if let posts = object {
for post in posts{
print(posts)
let objectIdVar = post ["objectId"] as? String
post.remove(forKey: "objectIdVar")
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
})
}
Thank you for your support
In remove function:
let objectIdVar = post ["objectId"] as? String
post.remove(forKey: "objectIdVar")
After removing post from firebase, you need to remove the image and comment from your class array's as well. Like:
self.comments.remove(post["message"] as! String)
self.imageFile.remove(post["imageFile"] as! PFFile)
Then reload table view.

Only show friends posts on Parse

new programmer trying to learn Swift and I'm trying to set my app up to only show the current users post on a parse photosharing database. The first method here in theory should add the current user to the "followingWho" array.
override func viewDidLoad() {
super.viewDidLoad()
let userQuery = PFUser.query()
userQuery?.whereKey("username", equalTo: PFUser.currentUser()!.username!)
userQuery?.findObjectsInBackgroundWithBlock ({
(objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
//no error
if let objects = objects {
for object in objects {
let followingWho = object["followingWho"] as! NSArray!
self.loadData(followingWho)
}
}
} else {
//error
NSLog("Error")
}
})
self.tableView.reloadData()
}
then my second method here should display the posts and filter out all but the current users
func loadData(followingWho: NSArray) {
let query = PFQuery(className: "Posts")
query.whereKey("addedBy", containedIn: followingWho as! [PFObject])
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock {
(posts: [PFObject]?, error: NSError?) -> Void in
if (error == nil) {
//No error
//let posts = posts as! [PFObject]
if let posts = posts {
for post in posts {
self.images.append(post["Image"] as! PFFile)
self.imageCaptions.append(post["Caption"] as! String)
self.imageDates.append(post["date"] as! String)
self.imageUsers.append(post["addedby"] as! String)
}
self.tableView.reloadData()
}
} else {
//error
NSLog("Error")
}
}
}
But nothing seems to be working. The code compiles and runs but it seems to only pull up a blank screen loading none of the posts.
This could be the problem, although if it is not the problem, it is certainly a problem: you are trying to update the UI from a background thread. findObjectsInBackgroundWithBlock calls its completion block in the background, and updating UI from the background is a big no-no. Instead, call your UI updates on the main thread:
dispatch_async(dispatch_get_main_queue(), {
//Do your UI updates here
})

Querying from Parse Classes

I am trying to query the user's from _User class, which I have managed successfully. But what I am trying to do now where I'm having a bit of difficulty, is query another class, Posts, and download the images that match the users downloaded from the first query?!
So I am just trying to assign the images from the Posts class to the correct users from the _User class...It sounds very simple, but it driving me mad!!
Here's my code for the query, I know it's probably not the best way but I'm newish to Swift! But I'm willing to try any tips or recommendations if you have any!
let userQuery = PFQuery(className: "_User")
userQuery.addDescendingOrder("createdAt")
userQuery.findObjectsInBackgroundWithBlock ({
(objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
self.profilePicArray.removeAll(keepCapacity: false)
self.usernameArray.removeAll(keepCapacity: false)
self.fullnameArray.removeAll(keepCapacity: false)
self.uuidArray.removeAll(keepCapacity: false)
for an object in objects! {
self.profilePicArray.append(object.valueForKey("profilePicture") as! PFFile)
self.usernameArray.append(object.valueForKey("username") as! String)
self.fullnameArray.append(object.valueForKey("firstname") as! String)
self.uuidArray.append(object.valueForKey("uuid") as! String)
}
let imageQuery = PFQuery(className: "Posts")
imageQuery.whereKey("username", containedIn: self.usernameArray)
imageQuery.findObjectsInBackgroundWithBlock({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
self.lastPicArray.removeAll(keepCapacity: false)
for an object in objects! {
self.lastPicArray.append(object.valueForKey("image") as! PFFile)
}
self.collectionView.reloadData()
} else {
print(error!.localizedDescription)
}
})
} else {
print(error!.localizedDescription)
}
})
The result I am getting at the moment is that: all user's download and also all the posts, but the images are just assigned randomly to each user or all the posts appear for each single user!
Thanks in advance.
New Query
func uu() {
let query = PFQuery(className: "_User")
query.addDescendingOrder("createdAt")
query.includeKey("latestImage")
query.whereKey("username", notEqualTo: PFUser.currentUser()!.username!)
query.findObjectsInBackgroundWithBlock { (object:[PFObject]?, error:NSError?) -> Void in
if error == nil {
for object in object! {
if (object.objectForKey("latestImage") != nil)
{
self.lastPicArray.append(object.objectForKey("latestImage")!.valueForKey("image") as! PFFile)
self.profilePicArray.append(object.valueForKey("profilePicture") as! PFFile)
self.fullnameArray.append(object.valueForKey("firstname") as! String)
self.usernameArr.append(object.valueForKey("username") as! String)
}
}
self.collectionView.reloadData()
print(self.usernameArr)
print(self.lastPicArray)
}
}
}
You should be able to do this with just one query, by using the includeKey function of Parse Queries
Parse Queries
Take your 2nd query, and add something like this:
let imageQuery = PFQuery(className: "Posts")
imageQuery.whereKey("username", containedIn: self.usernameArray)
imageQuery.includeKey("fieldNameOfUserPointer")
Just change the 'fieldNameOfUserPointer' to the field name that references your _User object in the Posts entity.

CollectionView flash when reloadData

I have a collectionView which is populated with around 60 images downloading from parse. These images can be updated depending if any new ones have been uploaded.
But my problem is after I load the view, and I refresh the data using PullToRefresh function, the collection view Flashes white and then displays the images again...
here's a video to show you :
https://www.youtube.com/watch?v=qizaAbUnzYQ&feature=youtu.be
I have been trying to fix this all day & find a solution, but I have had no success..!
Heres how I'm querying the images :
func loadPosts() {
self.activityView.startAnimating()
let followQuery = PFQuery(className: "Follows")
followQuery.whereKey("follower", equalTo: PFUser.currentUser()!.username!)
followQuery.findObjectsInBackgroundWithBlock ({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
self.followArray.removeAll(keepCapacity: false)
for object in objects! {
self.followArray.append(object.valueForKey("following") as! String)
}
let query = PFQuery(className: "Posts")
query.limit = self.page
query.whereKey("username", notContainedIn: self.followArray)
query.whereKey("username", notEqualTo: PFUser.currentUser()!.username!)
query.findObjectsInBackgroundWithBlock ({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
self.postImage.removeAll(keepCapacity: false)
self.uuidArray.removeAll(keepCapacity: false)
self.usernameArray.removeAll(keepCapacity: false)
for object in objects! {
self.postImage.append(object.valueForKey("image") as! PFFile)
self.uuidArray.append(object.valueForKey("uuid") as! String)
self.usernameArray.append(object.valueForKey("username") as! String)
}
} else {
print(error!.localizedDescription)
}
self.collectionView.reloadData()
self.refresher.endRefreshing()
self.activityView.stopAnimating()
self.boxView.removeFromSuperview()
})
}
})
}
And here is how I am pulling to refresh:
override func viewDidLoad() {
super.viewDidLoad()
refresher.addTarget(self, action: "reload", forControlEvents: UIControlEvents.ValueChanged)
collectionView.addSubview(refresher)
loadPosts()
}
func reload() {
collectionView.reloadData()
refresher.endRefreshing()
}
I assume that the UUID's are unique for every post, so you can check to see if the count from the previous load is different from the current, then you can see which posts are new, figure out their index path then only reload those index paths. I used sets to determine which id's had been added, which will work assuming you don't want to display the same post twice. There might be a better way of doing it, but in general you need to do something similar to the following:
func loadPosts() {
self.activityView.startAnimating()
let followQuery = PFQuery(className: "Follows")
followQuery.whereKey("follower", equalTo: PFUser.currentUser()!.username!)
followQuery.findObjectsInBackgroundWithBlock ({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
self.followArray.removeAll(keepCapacity: false)
for object in objects! {
self.followArray.append(object.valueForKey("following") as! String)
}
let query = PFQuery(className: "Posts")
query.limit = self.page
query.whereKey("username", notContainedIn: self.followArray)
query.whereKey("username", notEqualTo: PFUser.currentUser()!.username!)
query.findObjectsInBackgroundWithBlock ({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
let oldUUIDArray = self.uuidArray
self.postImage.removeAll(keepCapacity: false)
self.uuidArray.removeAll(keepCapacity: false)
self.usernameArray.removeAll(keepCapacity: false)
for object in objects! {
self.postImage.append(object.valueForKey("image") as! PFFile)
self.uuidArray.append(object.valueForKey("uuid") as! String)
self.usernameArray.append(object.valueForKey("username") as! String)
}
let uuidOldSet = Set(oldUUIDArray)
let uuidNewSet = Set(self.uuidArray)
let missingUUIDs = uuidNewSet.subtract(uuidOldSet)
let missingUUIDArray = Array(missingUUIDs)
let missingUUIDIndexPaths = missingUUIDArray.map{NSIndexPath(forItem:self.uuidArray.indexOf($0)!,inSe ction:0)}
let extraUUIDs = uuidOldSet.subtract(uuidNewSet)
let extraUUIDArray = Array(extraUUIDs)
let extraUUIDIndexPaths = extraUUIDArray.map{NSIndexPath(forItem:oldUUIDArray.indexOf($0)!,inSection:0)}
self.collectionView.performBatchUpdates({
if extraUUIDIndexPath != nil {
self.collectionView.deleteItemsAtIndexPaths(extraUUIDIndexPaths)
}
if missingUUIDIndexPaths != nil {self.collectionView.insertItemsAtIndexPaths(missingUUIDIndexPaths)}
}, completion: nil)
} else {
print(error!.localizedDescription)
}
self.refresher.endRefreshing()
self.activityView.stopAnimating()
self.boxView.removeFromSuperview()
})
}
})
}
func reload() {
self.loadPosts()
refresher.endRefreshing()
}

Parse query containedIn doesn't return any value

Several days I'm trying to crack why my code doesn't work and everything I've tried doesn't give me any result. Heres the deal:
There is a Booking class that contains userFrom who made booking
let query = PFQuery(className: "Booking")
query.whereKey("offer", equalTo: offer.pfObject!)
if self.typeOfUser == .COOK { //! If user is a Cook
query.findObjectsInBackgroundWithBlock({ (objects : [PFObject]?, error : NSError?) -> Void in
if let error = error {
print(error.localizedDescription)
} else {
if let objects = objects {
self.bookings = objects
self.usersIds = [String]()
for object in objects {
let userFrom = object.objectForKey("userFrom") as? PFObject
let userId = userFrom!.objectId! as String
self.usersIds.append(userId)
}
self.getUserInfoForBooking()
} else {
print("Something went wrong")
}
}
})
}
From every user I get objectId and append it to the [String] array. Then I query users with their IDs
private func getUserInfoForBooking() {
let userQuery = PFQuery(className: "User")
userQuery.whereKey("objectId", containedIn: self.usersIds)
userQuery.findObjectsInBackgroundWithBlock({ (objects : [PFObject]?, error : NSError?) -> Void in
if let error = error {
print(error.localizedDescription)
} else {
print(objects!)
if let objects = objects {
for object in objects {
self.users.append(object)
}
self.collectionView.reloadData()
}
}
})
}
In this query I always get an empty array.
Whatever I did, whatever I've changed always [] in response :(
This is the wrong way to query users
let userQuery = PFQuery(className: "User")
Because the class name is private. You should be creating the query as
let userQuery = PFUser.query()

Resources