How can I query after a specific row where the objectId is equal to a objectId I have stored?
This is my query code:
func queryStory(){
let query = PFQuery(className: "myClassStory")
query.whereKey("isPending", equalTo: false)
query.limit = 1000
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock { (posts: [PFObject]?, error: NSError?) -> Void in
if (error == nil){
// Success fetching objects
for post in posts! {
if let imagefile = post["userFile"] as? PFFile {
self.userFile.append(post["userFile"] as! PFFile)
self.objID.append(post.objectId!)
self.createdAt.append(post.createdAt!)
}
}
print("Done!")
}
else{
print(error)
}
}
}
This is my Parse database class:
What I want, is to only query the items that was createdAt after the objectId: woaVSFn89t. How can I do this?
Try filtering the objects once you have found them:
query.findObjectsInBackgroundWithBlock { (posts: [PFObject]?, error: NSError?) -> Void in
if (error == nil){
// Success fetching objects
var thePostTime = NSDate()
for post in posts! {
if post.objectId == "The Object Id You Were Trying To Find" {
thePostTime = post.createdAt!
}
}
for post in posts! {
if post.createdAt!.isGreaterThan(thePostTime) == true {
if let imagefile = post["userFile"] as? PFFile {
self.userFile.append(post["userFile"] as! PFFile)
self.objID.append(post.objectId!)
self.createdAt.append(post.createdAt!)
}
}
}
print("Done!")
}
else{
print(error)
}
}
You will notice that I compared the dates using this: NSDate Comparison using Swift
Before the for-loop make a variable:
var havePassedObjectId = false
Then inside the for-loop check if the current post is equal to the object id you want:
if post.objectid == "woaVSFn89t" {
self.userFile.append(post["userFile"] as! PFFile)
//Continue appending to arrays where needed
havePassedObjectId = true
} else if havePassedObjectId == true {
self.userFile.append(post["userFile"] as! PFFile)
//Continue appending to arrays where needed
}
This will check if you have already passed the object and append all the objects after.
Related
I am trying to run 4 queries from my parse database, each pulling just 1 object. I am trying to add each of the objects to an array that can then be used in a collection view. The queries run successfully but the app crashes because it is pulling null values. Here is my code:
var query1desc = ""
var query2desc = ""
var descs = [String]()
fileprivate func fetchUsers() {
let query1 = PFQuery(className: "Messages")
query1.limit = 1
query1.findObjectsInBackground{
(objects, error) -> Void in
if error == nil {
if objects?.count == 0 {
} else {
let object = objects![0] as! PFObject
self.query1desc = object["message"] as! String
}
}
}
let query2 = PFQuery(className: "Messages")
query2.limit = 1
query2.findObjectsInBackground{
(objects, error) -> Void in
if error == nil {
if objects?.count == 0 {
} else {
let object = objects![0] as! PFObject
self.query2desc = object["message"] as! String
}
}
}
self.descs = [self.query1desc, self.query2desc]
self.collectionView.reloadData()
Does anyone know of a way to fix this so that self.descs does not just provide nil values? When I print within the query itself I know that objects are being pulled. Thanks in advance.
I think desc variable holds nil value because your program is executing an array assignment code part while completion handlers are still processing query requests. You need to wait until all your query requests finish and then can collect all the results.
let workGroup = DispatchGroup()
let queueForQuery1 = DispatchQueue(label: "firstQuery")
let query1 = PFQuery(className: "Messages")
query1.limit = 1
workGroup.enter()
queueForQuery1.async(group:workGroup) {
query1.findObjectsInBackground{ (objects, error) -> Void in
if error == nil {
if objects?.count == 0 {
} else {
let object = objects![0] as! PFObject
self.query1desc = object["message"] as! String
}
}
workGroup.leave()
}
}
let queueForQuery2 = DispatchQueue(label: "secondQuery")
let query2 = PFQuery(className: "Messages")
query2.limit = 1
workGroup.enter()
queueForQuery2.async(group:workGroup) {
query2.findObjectsInBackground{ (objects, error) -> Void in
if error == nil {
if objects?.count == 0 {
} else {
let object = objects![0] as! PFObject
self.query1desc = object["message"] as! String
}
}
workGroup.leave()
}
}
workGroup.notify(queue: DispatchQueue.main){
self.descs = [self.query1desc, self.query2desc]
self.collectionView.reloadData()
}
How can I show live progress value when using this query?
Can I just a percent block or anything? How do I implement such thing?
func queryStory(){
self.userFile.removeAll()
self.objID.removeAll()
self.createdAt.removeAll()
let query = PFQuery(className: "myClass")
query.whereKey("isPending", equalTo: false)
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock { (posts: [PFObject]?, error: NSError?) -> Void in
if (error == nil){
// Success fetching objects
print("Post count:", posts!.count)
for post in posts! {
if let imagefile = post["userFile"] as? PFFile {
self.userFile.append(post["userFile"] as! PFFile)
self.objID.append(post.objectId!)
self.createdAt.append(post.createdAt!)
}
}
dispatch_async(dispatch_get_main_queue()) {
self.collectionView.reloadSections(NSIndexSet(index: 0))
if (self.refreshControlSpin == true){
self.refreshControlSpin = false
self.refreshControl.endRefreshing()
}
}
print("Uploaded files count: ", self.userFile.count)
}
else{
print(error)
}
}
}
To show percent value from 0 to 100, and changes live.
I get a warming of "Conditional cast from PFFile toPFFile always succeed" which highlighted if let tempProductPicture = self.askProductImageArray[0] as? PFFile. What is the best way to solve it? Thanks
var askProductImageArray = [PFFile]()
override func viewDidLoad() {
let query = PFQuery(className: "products")
query.whereKey("title", equalTo: labelTitleText)
query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error:NSError?) -> Void in
if error != nil {
}
for object in objects! {
self.askProductImageArray.append(object.objectForKey("detailsImage") as! PFFile)
self.askTable.reloadData()
}
if let tempProductPicture = self.askProductImageArray[0] as? PFFile {
tempProductPicture.getDataInBackgroundWithBlock { data, error in
if data == nil {
} else if error != nil {
} else {
self.productPicture.image = UIImage(data: data!)
}
}
}
}
Your self.askProductImageArray is an array of type PFFIle so there is no need to do as? PFFile because swift is strongly typed language and it will hold only PFFile so remover as? PFFile at the end.
In your case you don't need to do if let at all, you just need to check if item already exist.
you can do something like this
if self.askProductImageArray.count > 0 {
let tempProduct = self.askProductImageArray[0]
// and do rest
}
My Question is very simple,
I'm Learning iOS development and I'm stuck with tableviewcontroller
I can add Values to tableview with array, but when I try to append value from Parse, it's not working.
Here is the code:
var names: [String] = ["Name_one", "Name_two"]
let query: PFQuery! = PFUser.query()
override func viewDidLoad() {
super.viewDidLoad()
query.whereKey("objectId", notEqualTo: PFUser.currentUser()!.objectId!)
query.findObjectsInBackgroundWithBlock { objects, error in
if (error == nil) {
for user: PFUser in (objects as! [PFUser]) {
self.names.append(user.username as! String)
}
} else {
print("Error")
}
}
Screen Shot Attachment
You must to reload your tableview after get data finished
Code:
query.findObjectsInBackgroundWithBlock { objects, error in
if (error == nil) {
for user: PFUser in (objects as! [PFUser]) {
self.names.append(user.username as! String)
}
yourTableview.reloadData()
} else {
print("Error")
}
}
So I am saving some objects to the localDatastore using parse.
//Pin the objects here!!
var imageObject = PFObject(className: "img")
imageObject["theFile"] = imageFile
imageObject.pinInBackgroundWithBlock({ (success, error) -> Void in
if error == nil {
imageObject.saveEventually()
println("object pinned in background")
} else {
println(error)
}
})
Then in the viewDidLoad I am querying the objects and appending them into an array of PFFile's
var query = PFQuery(className: "img")
query.fromLocalDatastore()
query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if error == nil{
var objects : AnyObject = objects as! AnyObject
for object in objects as! [AnyObject]{
self.testImages.append(object["theFile"] as! PFFile)
}
} else {
println(error)
}
}
With this array now containing data. I am trying to insert the images into the tableView
if testImages.count >= 1{
testImages[indexPath.row].getDataInBackgroundWithBlock({ (imageData, error) -> Void in
if error == nil{
//The app crashes here ~ fatal error: unexpectedly found nil while unwrapping an Optional value
cell.theImage.image = UIImage(data: imageData!)
} else {
println(error)
}
})
}
Because you are using a tableview, I think the best way is to download all the images from Parse and save it to an array. Then in the cellForRowAtPath method then you assign each index of that array to the cell.imageView.image
var query = PFQuery(className:"img")
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error:NSError?) -> Void in
if error == nil
{
if let objects = objects as? [PFObject]
{
for one in objects
{
var pictureImage = one["theFile"] as! PFFile
pictureImage.getDataInBackgroundWithBlock({ (dataToget:NSData?, error:NSError?) -> Void in
if error == nil
{
if let Image = UIImage(data: dataToget)
{
// save the image to array
// reload the tableview
}
}
})
}
}
}
}