PFQuery with live progress - ios

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.

Related

Parse - Query after a specific row

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.

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()
}

Why do i get 0 pinned objects when i query LocalDatastore? iOS. Swift. Parse v1.7.5

func queryForPhotosFromLocalDatastore()
{
var xquery = PFQuery(className: "Follows")
xquery.fromLocalDatastore()
//xquery.whereKey("Follower", equalTo: PFUser.currentUser()!.objectId!)
xquery.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if let xobjects = objects
{
if xobjects.count > 0
{
for yobject in xobjects
{
println("Done")
}
}
else
{
println("number of objects is \(xobjects.count)")
}
}
else
{
println(error?.userInfo)
}
}
}
func queryForPhotosFromParse()
{
PFObject.unpinAllObjectsInBackgroundWithBlock(nil)
var xquery = PFQuery(className: "Follows")
xquery.whereKey("Follower", equalTo: PFUser.currentUser()!.objectId!)
xquery.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if let xobjects = objects
{
println("xobjects are \(xobjects.count)")
println("querying from parse")
for yobject in xobjects
{
var followedUser = yobject["Following"] as! String
var query = PFQuery(className: "Images")
query.whereKey("userID", equalTo: followedUser)
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock { (xobjects, error) -> Void in
if let objects = xobjects
{
PFObject.pinAllInBackground(objects, block: { (success, error) -> Void in
if error == nil
{
println("Pinned \(objects.count) objects")
self.queryForPhotosFromLocalDatastore()
}
})
}
else
{
println(error?.userInfo)
}
}
}
}
}
}
// The number of objects its returning (xobjects.count) is 0. Why is that so ?
I tried to have query localdatastore in my app but The number of objects its returning (xobjects.count) is 0. Why is that so ?
i have tried to query before with the previous versions but same thing happened. The latest version on parse says that they have fixed the error but I'm still getting the number of objects retrieved from localdatastore as "0". Please Help.

Problems When Trying to display images from Parse using Swift

I am trying to display an image from parse using swift. This is my code:
var query = PFQuery(className: "Maps")
query.getObjectInBackgroundWithId("1234asdf3456") {
(object: PFObject?, error: NSError?) -> Void in
if error == nil
{
println(object)
var objectAsPF = object as PFObject!
let file = objectAsPF["imageFile"] as! PFFile
file.getDataInBackgroundWithBlock {
(imageData:NSData?, error:NSError?) -> Void in
if error == nil {
if let imageData = imageData {
let map:UIImage = UIImage(data: imageData)!
self.MapView.image = map
println("success")
}
}
}
}
else
{
println(error)
}
}
I set a breakpoint at println("success") and i checked the variable values and everything is fine until i try to convert imageData to UIImage. Any tips?
Use this code to retrieve images from parse then convert it from a PFFile to a UIImage...
var query = PFQuery(className:"Maps")
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
self.scored = objects!.count
// Do something with the found objects
if let objects = objects as? [PFObject] {
for object in objects {
let userImageFile = object["imageFile"] as! PFFile
userImageFile.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let imageData = imageData {
let image = UIImage(data:imageData)
if image != nil {
self.imageArray.append(image!)
}
}
}
}
}
}
} else {
// Log details of the failure
println("Error: \(error!) \(error!.userInfo!)")
}
dispatch_async(dispatch_get_main_queue()) {
println("Finished Loading Image")
}

Updating Objects in iOS Swift with Parse

I've a table 'preferences' where user preferences are saved along with username. I created this method to update current user's preference' but somehow it doesn't seem to work. I am not sure if the portion "prefQuery.getObjectInBackgroundWithId(object.objectId)" is required at all.
I am new to Parse, could somebody please help me point what could be the issue.
func userPreferences(){
var currUser = PFUser.currentUser()
var prefQuery = PFQuery(className: "preferences")
var prefObj = PFObject(className: "preferences")
if let currUserName = PFUser.currentUser()?.username {
prefQuery.whereKey("username", equalTo: currUserName)
}
prefQuery.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
if let objects = objects as? [PFObject] {
for object in objects {
prefQuery.getObjectInBackgroundWithId(object.objectId){
(object: PFObject?, error: NSError?) -> Void in
if error == nil || object != nil {
prefObj["agestart"] = self.fromAge.text
prefObj["ageend"] = self.toAge.text
prefObj["location"] = self.location.text
ProgressHUD.showSuccess("Update successful")
} else {
ProgressHUD.showError("Update failed")
}
}
}
}
}
}
}
I found the issue and have updated my codes. The working codes are below; the issue was with the "prefObj["agestart"]" block of codes where I was using the wrong Query instance. You can compare the two snippets:
func userPreferences(){
var currUser = PFUser.currentUser()
var prefQuery = PFQuery(className: "preferences")
var prefObj = PFObject(className: "preferences")
if let currUserName = PFUser.currentUser()?.username {
prefQuery.whereKey("username", equalTo: currUserName)
}
prefQuery.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
if let objects = objects as? [PFObject] {
for object in objects {
prefQuery.getObjectInBackgroundWithId(object.objectId){
(prefObj: PFObject?, error: NSError?) -> Void in
if error != nil {
println(error)
ProgressHUD.showSuccess("Error while updating")
} else if let prefObj = prefObj {
prefObj["agestart"] = self.fromAge.text
prefObj["ageend"] = self.toAge.text
prefObj["location"] = self.location.text
ProgressHUD.showSuccess("Update successful")
prefObj.saveInBackgroundWithBlock({ (Bool, error: NSError!) -> Void in })
}
}
}
}
}
}
}
The best way to cut your code to the maximum, you can see below:
func userPreferences() {
let prefQuery = PFQuery(className: "preferences")
if let currUserName = PFUser.current()?.username {
prefQuery.whereKey("username", equalTo: currUserName)
}
prefQuery.findObjectsInBackground {
(objects, error) in
if error == nil {
if let objects = objects {
for object in objects {
object["agestart"] = "ur value"
object["ageend"] = "ur value"
object["location"] = "ur value"
print("Update successful")
object.saveInBackground()
}
}
}
}
}

Resources