Return Uiimage Array from Parse Query Block

how can I add UIImages to my PFFile array so that if query for a PFFIle images fails, it can be replaced by appending an UIImage?

Your app is crashing because you have more table view cells than pictures in picturesArray

Just check if indexPath.row < picturesArray.count before using picturesArray[x]

if indexPath.row < picturesArray.count {
self.picturesArray[indexPath.row].getDataInBackgroundWithBlock { (imageData: NSData?, error:NSError?) -> Void in

if error == nil {
let image = UIImage(data: imageData!)
cell.senderProfileImage?.image = image
}

}
} else {
cell.senderProfileImage?.image = UIImage(named: "logo")
}

Edit:

If you want to append a PFFile with the logo image into picturesArray you can do the following

let imageData:NSData = UIImagePNGRepresentation(UIImage(named: "imagename")!)!
self.picturesArray.append(PFFile(data: imageData))

instead of

self.picturesArray.append(UIImage(named: "logo"))

Explanation:

Here self.picturesArray.append(UIImage(named: "logo")) you were trying to add an UIImage object to and array that only accepts PFFile objects, as you declared here: var picturesArray : [PFFile] = []

You need to instantiate a new PFFile and add an UIImage to it, but the PFFile initialiser only accepts NSData to store.

So to transforma an UIImage into NSData you can use UIImagePNGRepresentation and then instantiate the PFFile with the image data.

Swift Image retrieving from Parse sdk - getting crashed

I managed to recreate the error, which seems to be some kind of memory leak / zombie on a PFObject. I'm not sure exactly why, but refactoring your code in the following manner got rid of the error in my case:

func loadImages() {

var query = PFQuery(className: "Images")
query.orderByDescending("objectId")

query.findObjectsInBackgroundWithBlock ({(objects:[AnyObject]!, error: NSError!) in
if(error == nil){

self.getImageData(objects as [PFObject])

}
else{
println("Error in retrieving \(error)")
}

})//findObjectsInBackgroundWithblock - end

}

func getImageData(objects: [PFObject]) {
for object in objects {

let thumbNail = object["image"] as PFFile

println(thumbNail)

thumbNail.getDataInBackgroundWithBlock({
(imageData: NSData!, error: NSError!) -> Void in
if (error == nil) {
let image = UIImage(data:imageData)
//image object implementation
self.imageResources.append(image)
println(image)
}

})//getDataInBackgroundWithBlock - end

}//for - end
}

EDIT: Incidentally, this also works:

func loadImages() {

var query = PFQuery(className: "Images")
query.orderByDescending("objectId")

query.findObjectsInBackgroundWithBlock ({(objects:[AnyObject]!, error: NSError!) in
if(error == nil){

let imageObjects = objects as [PFObject]

for object in objects {

let thumbNail = object["image"] as PFFile

thumbNail.getDataInBackgroundWithBlock({
(imageData: NSData!, error: NSError!) -> Void in
if (error == nil) {
let image = UIImage(data:imageData)
//image object implementation
self.imageResources.append(image)
println(image)
}

})//getDataInBackgroundWithBlock - end

}//for - end

}
else{
println("Error in retrieving \(error)")
}

})//findObjectsInBackgroundWithblock - end

}

This would indicate that the error was due to the following line:

for object : PFObject! in objects as [PFObject] {

Rewriting that line as follows:

for object : PFObject in objects as [PFObject] {

Also removes the error. So the reason for this error seems to be that that you told the program to unwrap something that wasn't an optional.

Retrieve multiple images from Parse with getdatainbackground (IOS - Swift)

Your analysis is correct that the requests will complete in non-deterministic order, partly or mostly influenced by the amount of data that must be returned.

Instead of an array to which you append the UIImage (or data), use a mutable dictionary that maps strings to UIImage. A reasonable choice for the string key is the PFFile name.

EDIT I'm not a Swift writer, but I tried to express the idea below (don't depend on it compiling, but I think the idea is sound)

class MyClass {    
var objects: [PFObject] = []
var images: [String: UIImage] = [:] // we'll map names to images

fetchObjects() {
// form the query
query.findObjectsInBackground (block: { (objects:[PFObject]?, error: Error?) -> Void in
self.objects = objects
self.fetchImages()
})
}

fetchImages() {
for object in self.objects! {
if let imageFile : PFFile = object["Bild"] as PFFile {
self.fetchImage(imageFile);
}
}
}

fetchImage(imageFile: PFFile) {
imageFile.getDataInBackground(block: { (data, error) in
if error == nil {
self.images[imageFile.name] = UIImage(data: data!)
// we can do more here: update the UI that with image that has arrived
// determine if we're done by comparing the count of images to the count of objects
} else {
// handle error
}
}
}
}

This will get the images in the background and keep them associated with their filenames using a dictionary. The OP code didn't explain what self.bild is, but I assumed it was an instance array of retrieved PFFiles. I replaced this with the images instance var.

Image file order is maintained by the object collection: to get the Nth image, get the Nth object, get it's "Bild" property, that PFFile's name is the key into your images dictionary.

var n = // some index into objects
var object : PFObject = self.objects[n]
var file : PFFile = object["Bild"]
var name : String = file.name
var nthImage = self.images[name] // is nil before fetch is complete

How to load an image from Parse into a UIImageView (iOS)

For anyone who needs help! I found the answer to my question.

Found it in this example:
https://parse.com/questions/retrieve-images-from-parse-to-uiimageview

Hope it helps for someone else!!

And thanks to all who took the time to answer my question!

return an Array with swift2 from parse server

you are parsing one imageData in success block, so if you want Events collectively to show somewhere else, you need to keep appending Event(featuredImage: UIImage(data: data)!) in class property arrayEvents(lets say) and reload data on each append since its updating.

Swift - UIImage and Nil Value

This is happening because the function completes before the tasks within the closures do.

You should make tempImage a property of self and have the closures update that property.

class SomeClass {

var tempImage: UIImage?

func someFuncToGetStuff() {

Parse.doParseStuffWithCompletion(fetchedPFFile) -> Void in

let myImage = UIImage(data: fetchedPFFile)
self.tempImage = myImage

}

}

}

How to run a loop of parse queries?

Found it. Not the prettiest way out there but well it does what i want. gets me arrays of usernames and profile pictures of every objectID contained in array of friends.

 NSMutableArray * objectIDs = [[NSMutableArray alloc] initWithArray: sharedClass.sharedInstance->retrievedFriends];
PFQuery *query = [PFUser query];
PFFile * imageFile;
//UIImage *profilePictureData;
int friendsCount = [objectIDs count];
for(int i = 0; i<friendsCount;i++)
{
PFObject * username = [query getObjectWithId:objectIDs[i]];
[sharedClass.sharedInstance->friendsUsernames addObject:username[@"username"]];
[sharedClass.sharedInstance->friendsEmailAdresses addObject:username[@"email"]];
//NSLog(@"%@",username[@"ProfilePicture"]);
imageFile = [username objectForKey:@"ProfilePicture"];
NSData *imageData = [imageFile getData];
UIImage *imageFromData = [UIImage imageWithData:imageData];
[sharedClass.sharedInstance->friendsProfilePictures addObject:imageFromData];
NSLog(@"%@", sharedClass.sharedInstance->friendsUsernames );
}

How to convert an PFFile to an UIImage with swift?

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


Related Topics



Leave a reply



Submit