[フレーム]
Last Updated: February 25, 2016
·
5.441K
· sirvine

Load Images from Parse.com to iOS App

Parse.com allows you to persist file objects, including images. In your iOS app, you'll likely want to load these in a sensible way that takes into account network lag.

In this case, we're going to use Parse.com's getDataInBackgroundWithBlock method, and we're going to pass a completion block to our caller when the download is completed (or if an error occurs). You can also pass an optional UIProgressView to the method, if you want to display a progress bar on screen.

The most reusable way to implement this is to create new category on PFObject and add this class method to your category's .h file:

+(void)loadParseImage:(PFObject *)parseObject forImageColumn:(NSString *)columnName withProgressBar:(UIProgressView *)progressBar andCompletionBlock:(void (^)(UIImage *imageFile, NSError *error))completionBlock;

Then in the category's .m file, add the following method:

+(void)loadParseImage:(PFObject *)parseObject forImageColumn:(NSString *)columnName withProgressBar:(UIProgressView *)progressBar andCompletionBlock:(void (^)(UIImage *imageFile, NSError *error))completionBlock
{
 NSString *parseFileName = [NSString stringWithFormat:@"%@", [[parseObject objectForKey:columnName] name]];
 // Get a path to the place in the local documents directory on the iOS device where the image file should be stored.
 NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
 // You can change the path as you see fit by altering the stringByAppendingPathComponent call here.
 NSString *imagesDirectory = [documentsDirectory stringByAppendingPathComponent:@"Images"];
 NSString *storePath = [imagesDirectory stringByAppendingPathComponent:parseFileName];
 if (progressBar)
 {
 // Reset and show the progress bar
 [progressBar setProgress:0.0 animated:NO];
 progressBar.hidden = NO;
 }
 // Image data from Parse.com is retrieved in the background.
 [[parseObject objectForKey:columnName] getDataInBackgroundWithBlock:^(NSData *data, NSError *error)
 {
 if (!error)
 {
 NSData *fileData = [[NSData alloc] initWithData:data];
 if (![[NSFileManager defaultManager] fileExistsAtPath:imagesDirectory])
 {
 // Create the folder if it doesn't already exist.
 [[NSFileManager defaultManager] createDirectoryAtPath:imagesDirectory
 withIntermediateDirectories:NO
 attributes:nil
 error:&error];
 }
 // Write the PFFile data to the local file.
 [fileData writeToFile:storePath atomically:YES];

 UIImage *showcaseImage;
 if ([[NSFileManager defaultManager] fileExistsAtPath:imagesDirectory])
 {
 showcaseImage = [UIImage imageWithContentsOfFile:storePath];
 }
 else // No file exists at the expected path. Perhaps the disk is full, etc.?
 {
 NSLog(@"Unable to find image file where we expected it: %@", storePath);
 }
 completionBlock(showcaseImage, error);
 // This may be a good place to clean up the target directory.
 }
 else // Unable to pull the image data from Parse.com. Consider more robust error handling.
 {
 NSLog(@"Error getting image data.");
 completionBlock(nil, error);
 }
 }
 progressBlock:^(int percentDone)
 {
 if (progressBar)
 {
 [progressBar setProgress:percentDone animated:YES];
 }
 }];
}

The class method expects you to pass a PFObject first, then an NSString representing the name of the column on Parse.com where your PFFile is stored, and an optional UIProgressView.

Now, assuming that you have a UIViewController with the following property declarations in its .h file:

@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIProgressView *progressBar;

You can load the images from any other part of your UIViewController's .m file, for example from viewDidLoad:

- (void)viewDidLoad
{
 [super viewDidLoad];
 [PFObject loadParseImage:myPFObject forImageColumn:@"MainImage" withProgressBar:self.progressBar andCompletionBlock:^(UIImage *imageFile, NSError *error) 
 {
 if (!error)
 {
 self.imageView.image = imageFile;
 }
 else
 {
 // Image file did not load correctly. Handle the error as you see fit.
 }
 }];
}

Remember: you'll need to #include your new PFObject category in any UIViewControllers or other objects that will access the class method.

3 Responses
Add your response

Hi! Thanks for the tutorial.. I do get an error though:

"Use of undeclared identifier 'myPFObject'"

why do you think?

over 1 year ago ·

Adrienne: you probably need to replace 'myPFObject' with the actual instance of the PFObject that has the image as a property. Typically, you want to query for the PFObject first, then pass it into this loadParseImage:forImageColumn:withProgressBar:andCompletionBlock method to pull the image down. Note that you'll also want to change "MainImage" to match the name you gave the image column in Parse. HTH.

over 1 year ago ·

I'm having the same issue. I'm in parse and i don't see an option for image name. All i have is the objectid and the name of the pffile.

over 1 year ago ·

AltStyle によって変換されたページ (->オリジナル) /