How to retrieve a image from Parse? - ios

I'm trying to get an image from a parse server that is hosted on Heroku. So far I have gotten the Text values but the images are the only problem.
Here is my code so far:
// Getting Info from servers
let dataQ = PFQuery(className: "message")
dataQ.findObjectsInBackground { (objects: [PFObject]?, error: Error?) -> Void in
if error == nil {
for object in objects! {
self.sentFromLabel.text = object["sender"] as? String
// Get Image from server
object["Picture"].getDataInBackgroundWithBlock
}
} else {
print(error)
}
}
So far when I use .getDataInBackgroundWithBlock it gives me an error. I have no clue why. What is the Swift 3 version to allow me to get an image from the server?

Here is a swift 3 example!
#IBOutlet weak var fullImage : UIImageView!
//place this in your for loop
let imageFile = (object.object(forKey: "ImageFile") as? PFFile)
imageFile?.getDataInBackground (block: { (data, error) -> Void in
if error == nil {
if let imageData = data {
//Here you can cast it as a UIImage or do what you need to
self.fullImage.image = UIImage(data:imageData)
}
}
})

Related

One image pulled from Parse when there are actually two : weird error.

I have the following function that's suppose to pull images from a class in Parse. The number of images in the class is two and the print line print(objectsFound?.count) prints out 2 - confirming there are two images
func loadAllObjects() {
let discoveryQuery = PFQuery(className: "DiscoveryDetails")
discoveryQuery.cachePolicy = .NetworkElseCache
discoveryQuery.whereKey("discoveryID", equalTo: PFObject(withoutDataWithClassName: "Discovery", objectId: "\(varInDDT!.objectId!)"))
discoveryQuery.orderByDescending("createdAt")
discoveryQuery.findObjectsInBackgroundWithBlock { (objectsFound: [PFObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
print(objectsFound?.count) //This prints out 2
for var i = 0; i < objectsFound?.count; i++ {
if let imageFileFound = objectsFound![i].objectForKey("workoutImage") as? PFFile {
imageFileFound.getDataInBackgroundWithBlock { (imageData: NSData?, error: NSError?) -> Void in
if (error == nil) {
self.arrayOfWorkoutImages = [UIImage(data:imageData!)!]
}
}
}
}
} else {
//An error Occured
self.showFailureAlert("😐 Failed to get workout Images", detailedMessage: "Check your network settings and try again", buttonMessage: "Ok")
}
}
}
I want to load the images into an array where I can use them later.
The line self.arrayOfWorkoutImages = [UIImage(data:imageData!)!] adds them to the array
var arrayOfWorkoutImages: [UIImage] = []
On trying to see whether the images are pulled (checking the print(self.arrayOfWorkoutImages) and print(self.arrayOfWorkoutImages.count) ) I get only ONE image counted and pulled. This is the function I am using that is linked to a button that does this.
#IBAction func addbuttonPressed(sender: AnyObject) {
self.loadAllObjects()
print(self.arrayOfWorkoutImages)
print(self.arrayOfWorkoutImages.count)
}
Any ideas on what I could be doing wrong. This is has been throwing errors at me for a couple of days now!! :(
Your code contains an error: for each object you re-assign to arrayOfWorkoutImages an array with the retrieved image.
func loadAllObjects(completion: () -> Void) {
let discoveryQuery = PFQuery(className: "DiscoveryDetails")
discoveryQuery.cachePolicy = .NetworkElseCache
discoveryQuery.whereKey("discoveryID", equalTo: PFObject(withoutDataWithClassName: "Discovery", objectId: "\(varInDDT!.objectId!)"))
discoveryQuery.orderByDescending("createdAt")
discoveryQuery.findObjectsInBackgroundWithBlock { (objectsFound: [PFObject]?, error: NSError?) -> Void in
if error == nil {
for var i = 0; i < objectsFound?.count; i++ {
if let imageFileFound = objectsFound![i].objectForKey("workoutImage") as? PFFile {
imageFileFound.getDataInBackgroundWithBlock { (imageData: NSData?, error: NSError?) -> Void in
if (error == nil) {
if let data = imageData, image = UIImage(data: data) {
self.arrayOfWorkoutImages.append(image)
}
}
}
}
}
}
completion()
}
}

PFFile to UIImage [duplicate]

How do i convert an PFFile to an UIImage with swift?
In this code, the app is getting the file from parse and now i want it to show on a UIImageView, But i get an error...
Here is my code...
var ImageArray:UIImage = [UIImage]()
var textArray:String = [String]()
var query = PFQuery(className:"ClassName")
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
if let objects = objects as? [PFObject] {
for object in objects {
//this works fine
self.textArray.append(object.valueForKey("Image")! as! String)
//this does not work...
self.ImageArray.append(object.valueForKey("Image")! as! PFFile)
//I get an error that says PFFile is not convertible to UIImage. How do i convert it?
}
}
} else {
// Log details of the failure
println("Error: \(error!) \(error!.userInfo!)")
}
PFFile is a parse representation of anykind of file. To get the "real" file (image), you need to call getDataInBackgroundWithBlock. Try it:
if let userPicture = object.valueForKey("Image")! as! PFFile {
userPicture.getDataInBackgroundWithBlock({
(imageData: NSData!, error NSError!) -> Void in
if (error == nil) {
let image = UIImage(data:imageData)
self.ImageArray.append(image)
}
})
}
Swift 1.2+ Version
if let userPicture = PFUser.currentUser()!.valueForKey("Image") as? PFFile {
userPicture.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
let image = UIImage(data:imageData!)
self.ImageArray.append(image)
}else{
print("Error: \(error)")
}
}
}
With Swift 3 on Parse.
if let photo = obj.file as? PFFile {
photo.getDataInBackground(block: {
PFDataResultBlock in
if PFDataResultBlock.1 == nil {//PFDataResultBlock.1 is Error
if let image = UIImage(data:PFDataResultBlock.0!){
//PFDataResultBlock.0 is Data
photoCell.attachedPicture.image = image
}
}
})
}

How to save images to Parse?

For some odd reason, my images have stopped saving to parse. Before, my code worked fine and I have not made any changes to it at all.
Here is my code:
var posts = PFObject(className: "Product")
posts["shortDescription"] = productShortDescription
posts["user"] = PFUser.currentUser()
posts["longDescription"] = productLongDescription
posts["title"] = productTitle
posts["price"] = productPrice
posts.saveInBackgroundWithBlock({
(success: Bool, error: NSError?) -> Void in
if error == nil {
//success saving, now save image
//create image data
var imageData = UIImagePNGRepresentation(self.newItemImageView.image)
//create parse file
var parseImageFile = PFFile(name: "upload_image.png", data: imageData)
posts["imagePNG"] = parseImageFile
posts.saveInBackgroundWithBlock({
(success: Bool, error: NSError?) -> Void in
if error == nil {
// take user home
println("data uploaded")
self.performSegueWithIdentifier("returnHomeAfterUpload", sender: self)
}else {
println(error)
}
})
}else {
println(error)
}
})
Everything else is stored perfectly, but what's the issue with my image data?
Thanks!
In your code you are not saving parseImageFile, so first parseImageFile.SaveInBackground and on success set it to posts and then save posts as well
Should be something like this
var posts = PFObject(className: "Product")
posts["shortDescription"] = productShortDescription
posts["user"] = PFUser.currentUser()
posts["longDescription"] = productLongDescription
posts["title"] = productTitle
posts["price"] = productPrice
posts.saveInBackgroundWithBlock({
(success: Bool, error: NSError?) -> Void in
if error == nil {
//success saving, now save image
//create image data
var imageData = UIImagePNGRepresentation(self.newItemImageView.image)
//create parse file
var parseImageFile = PFFile(name: "upload_image.png", data: imageData)
parseImageFile.saveInBackgroundWithBlock({
posts["imagePNG"] = parseImageFile
posts.saveInBackgroundWithBlock({
(success: Bool, error: NSError?) -> Void in
if error == nil {
// take user home
println("data uploaded")
self.performSegueWithIdentifier("returnHomeAfterUpload", sender: self)
}else {
println(error)
}
})
})
}else {
println(error)
}
})
I haven't test this code on editor you may find some syntax error, but it should be something like this...
so things is when you create parseImageFile and then saveInBackground and inside block set it posts and then save post again
I've checked your code and it's works fine.
let image = UIImage(named: "img.jpg")
let data = UIImagePNGRepresentation(image)
let file = PFFile(name: "img", data: data)
let parseObj = PFObject(className: "testClass")
parseObj["text"] = "hello"
parseObj["image"] = file
parseObj.saveInBackgroundWithBlock { (_, _) -> Void in }
Try this, if this code will be works - easiest way for you is remove "Product" table and create it again.

Better way to retrieve multiple images from Parse

Noob question here and I know my code below is very wrong but it works in that it retrieves the 3 images I need. However, I'd like to know a better way to retrieve multiple images from Parse.
Any help would be greatly appreciated!
func retrieveImage() {
var query = PFQuery(className: "Items")
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
let imageObjects = objects as! [PFObject]
for (index, object) in enumerate(imageObjects) {
let thumbnail1 = object["image1"] as! PFFile
let thumbnail2 = object["image2"] as! PFFile
let thumbnail3 = object["image3"] as! PFFile
thumbnail1.getDataInBackgroundWithBlock{(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let image = UIImage(data: imageData!) {
self.itemImages[index] = image
}
}
thumbnail2.getDataInBackgroundWithBlock{(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let image = UIImage(data: imageData!) {
self.itemImages2[index] = image
}
}
}
thumbnail3.getDataInBackgroundWithBlock{(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let image = UIImage(data: imageData!) {
self.itemImages3[index] = image
}
}
}
}
}
}
}
}
First the idea... we want to do an arbitrarily long list of asynch tasks, collect their results, and be notified on completion or error. We do this by parameterizing the task (in this case, the PFFiles whose contents are to be fetched are the parameters), and we use those parameters as a "to-do list".
A recursive function does the work, picking off the first item in the list, doing the asynch task, and then calling itself with the remainder of the list. An empty to-do list means we're done.
I've tried to translate the answer I referred to here into swift (literally learning the language line by line)....
func load(pfFiles: Array<PFFile>, var filling: Dictionary<PFFile, UIImage>, completion: (success: Bool) -> Void) {
completion(success: true)
var count = pfFiles.count
if (count == 0) {
return completion(success: true)
}
var file = pfFiles[0]
var remainder = Array(pfFiles[1..<count])
file.getDataInBackgroundWithBlock{(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let image = UIImage(data: imageData!) {
filling[file.name] = image
self.load(remainder, filling: filling, completion: completion)
}
} else {
completion(success: false)
}
}
}
Given this is my first attempt, I'll be a little shocked and delighted if it works, but the algorithm is sound, and the swift compiles and appears to match the idea I outlined. Here's how to call it...
var pfFiles: Array<PFFile>
for (index, object) in enumerate(imageObjects) {
pfFiles.append(object["image1"])
pfFiles.append(object["image2"])
pfFiles.append(object["image3"])
}
var filling: Dictionary<String, UIImage>
// call the function here
// in the completion assign filling to property
// anytime after, when you have a PFFile like someObject["image2"]
// you use its name to look it up the UIImage in the results dictionary
Let me know if that last bit is clear enough. As you can see, I ran out of steam on my swift translation and resorted to pseudo code.
I believe you can just do self.itemImages[index] = thumbnail1.getData()!
If it crashs, do : query.includeKey("image1")
NOTE:
If you afraid to block the main queue, open a new thread to do such thing

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

Resources