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
Pausing Timer When App Is in Background State Swift
How to Cluster Custom Icons Markers in Googlemaps for iOS
Uitableviewcell with Intrinsic Height Based on Width
How to Adjust the Uitableviewcell Height to the Content of Uitextview That's Inside
Passing Data Between Interface Controllers in Watchkit
Change Uitabbar Tint Colors in the More Menu
Swift: Triggering Tableviewcell to Lead to a Link in a Uiwebview in Another Viewcontroller
Nsfilemanager Moveitem Throws Error Code=513
The Array Value Should Be Sort Like (Alphabetic, Numbers and Special Characters)
How Should Secure Transport Tls Be Used with Bsd Sockets in Swift
Swift: Sort Array by Sort Descriptors
Empty Return Value from Swift Function Containing Closure
Can't Copy File from Bundle to Documents Directory in iOS
Calculate New Coordinates with Starting Position and Distance
How to Turn Off Core Data Write-Ahead Logging in Swift Using Options Dictionary