Swift 3: cant get image from Parse? - swift

Ok, I have looked at questions like How do you access an object's fields from a Parse query result in Swift? but the answer is not working in Swift 3. With the following trying to get an image from the first PFObject in Parse I get the error:
Cannot convert value type NSData, NSError -> Void to expected
PFDataResultBlock ?
var query = PFQuery(className: PARSE_CLASS!)
query.order(byDescending: "createdAt")
query.findObjectsInBackground {
(objects, error) -> Void in
if error == nil {
//print(objects?.first?["testTxt"] as! NSString)
//print(objects?.first?["testImg"] as! PFFile)
let thumbnail = objects?.first?["testImg"] as! PFFile
thumbnail.getDataInBackgroundWithBlock{(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let image = UIImage(data: imageData!) {
//get image here
}
}
}
}
I have tried changing the type and everything. How can I store an image from Parse in recent Swift?

You can try this:
if let validObjects = objects {
for object in validObjects {
let thumbnail = object["testImg"] as? PFFile
thumbnail?.getDataInBackground (block: { (data, error) -> Void in
//read image here
}
}
}

Related

Swift getting image from Parse.com and setting image with it

Trying to get an image from parse and set a uiimage with it but keep getting this error. Running Xcode 7 and swift 2.0
Cannot invoke 'getDataInBackgroundWithBlock' with an argument list of type '(imageData:NSData,error:NSError.Type,()->())'
let query: PFQuery = PFQuery(className: "Items")
query.whereKey("ItemOwner", equalTo: "Shreddish")
// 3
query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if error == nil {
print("Successfully retrieved: \(objects)")
for object in objects! {
print(object)
let imageFile: PFFile = object["ItemMainImage"] as! PFFile
var image = imageFile.getData()
imageFile.getDataInBackgroundWithBlock(imageData: NSData, error: NSError) {
}
}
} else {
print("Error: \(error) \(error!.userInfo)")
}
}
Change
imageFile.getDataInBackgroundWithBlock(imageData: NSData, error: NSError) {
...
}
To
imageFile.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
...
}

Loading images from parse.com

This is my saving image to parse:
func uploadPost(){
var imageText = self.imageText.text
if (imageView.image == nil){
println("No image uploaded")
}
else{
var posts = PFObject(className: "Posts")
posts["imageText"] = imageText
posts["uploader"] = PFUser.currentUser()
posts.saveInBackgroundWithBlock({ (success: Bool, error: NSError?) -> Void in
if error == nil{
//**Success saving, now save image.**//
// Create an image data
var imageData = UIImagePNGRepresentation(self.imageView.image)
// Create a parse file to store in cloud
var parseImageFile = PFFile(name: "upload_image.png", data: imageData)
posts["imageFile"] = parseImageFile
posts.saveInBackgroundWithBlock({ (success: Bool, error: NSError?) -> Void in
if error == nil{
// Take user home
println("Data uploaded")
}
else{
println(error)
}
})
}
else{
println(error)
}
})
}
}
How can I load the images from parse? This is how my Parse.com "Posts" data looks like:
Any suggestions?
I think maybe something like using this:
self.imageView.sd_setImageWithURL(url, completed: block)
But I donĀ“t know how I get the URL. And what if the images has different names?
try something like this
let imageFile = pfObject["imageFile"] as? PFFile
if imageFile != nil{
imageFile!.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let imageData = imageData {
self.imageView.image = UIImage(data: imageData)!
}
}
}
}
Where pfObject is the reference to your object. There are other ways you could check for a nil value, but this should work.
As long as you have a reference to the correct object (which you can get via a query for objectId) then you should only need the name of the column the image is file is stored in and not the image file itself.

How to retrieve image from parse and display it in a UIImageView in swift?

So I have been trying to retrieve an image from Parse since yesterday and I am very confused. I read similar questions and examples but all of them were people saving some image first, then retrieving it. What I want to do is simply retrieve an image that I manually uploaded to parse, I have been trying with this:
//Retrieving image from parse
var object = PFObject(className:"ClassImage")
let getParseImg = object["image"] as! PFFile
getParseImg.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
if (error == nil){
if let imageData = imageData{
println("Retrieving Image")
let img = UIImage(data:imageData)
self.imageView.image = img
}
}
}
In line two, it throws a "unexpectedly found nil while unwrapping an Optional value", I already tried "if let getParseImg", then it throws another error, in the end the line ended up looking like this:
if let getParseImg = object["image"] as? PFFile{
So after that, everything goes fine and compiles but it doesn't do absolutely anything, it does not get and display the image and it doesn't even print "Retrieving Image", any ideas how can I solve this, I am new to Parse so still getting familiarized with it.
Thanks in advance!
You need to run a query. Also, I used a dictionary called imagesDict in order to ensure your photos are returned in the correct order.
var query = PFQuery(className: "ClassImage")
query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
let imageObjects = objects as! [PFObject]
for (index, object) in enumerate(imageObjects) {
let thumbnail = object["image"] as! PFFile
thumbnail.getDataInBackgroundWithBlock{(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let image = UIImage(data: imageData!) {
self.imagesDict[index] = image
self.theTableView.reloadData()
}
}
}
}
}
}

Parse PFFile download order iOS in Swift

I'm trying to retrieve images from Parse as PFFiles but the order in which they are returned changes every time. I found another question/answer that addresses this problem but it's in Obj-C and after an hour, I cannot translate a working solution in Swift.
Here's the original thread:
Parse PFFile download order iOS
And here's my code:
func retrieveItemImage() {
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 object in imageObjects {
let thumbnail = object["image1"] as! PFFile
thumbnail.getDataInBackgroundWithBlock{(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let image = UIImage(data: imageData!) {
self.images.append(image)
self.theTableView.reloadData()
}
}
}
}
}
self.theTableView.reloadData()
}
}
I would make it that way:
var images = [Int: UIImage]()
Make it a dictionary, then you get an optional result of subscript and never have an array out of range exception.
Then I would rewrite the part of your code as:
for (index, object) in enumerate(imageObjects) {
let thumbnail = object["image1"] as! PFFile
thumbnail.getDataInBackgroundWithBlock{(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let image = UIImage(data: imageData!) {
self.images[index] = image
You never know the order of async operations completion, but your images will be in specified order, or nil in dictionary. You should also correct your tableView methods to check it for nil. Also, in my opinion, reloading the whole table after each image loading is ineffective.

Error when retrieving PFFile via getDataInBackgroundWithBlock

I have created a var userImages = [PFFile]() and have appended the respective user images from Parse via a user query and self.userImages.append(user["imageFile"] as! PFFile). This works fine. However, when I try to set the image of the user via
userImages.getDataInBackGroundWithBlock{ (data, error) -> Void in ...
I'm receiving the following error: **'[(PFFile)]' does not have a member named 'getDataInBackGroundWithBlock'**
Why doesn't this work and what might be a solution for this issue?
Thank you for the help!!
You are trying to call getDataInBackGroundWithBlock in a array try to use"
userImages.last?.getDataInBackGroundWithBlock{...}
or you can save it in a variable and use the new PFFIle to retrieve the image
let userImage = user["imageFile"] as! PFFile
userImage.getDataInBackGroundWithBlock{...}
or access it directly using:
(user["imageFile"] as! PFFile).getDataInBackGroundWithBlock{...}
The role process being:
self.userImages.append(user["imageFile"] as! PFFile) //This is just a reference to download the image
userImages.last?.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let imageData = imageData {
let image = UIImage(data:imageData) // this is the final image
}
}
}