Reputation: 1526
I'm trying to adapt the use of a UICollectionViewController I'm populating with an Array of local images to get the images from Parse.
So far it's pretty straightforward. My NSArray is filled with the same local image many times:
testImages = [NSArray arrayWithObjects: @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", @"thumbnail.jpg", nil];
On the collectionView:cellForItemAtIndexPath: I do set up my cell (from Storyboard):
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
// Set up cell identifier that matches the Storyboard cell name
static NSString *identifier = @"Cell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
// Configure the cell to show photo thumbnail
UIImageView *testImageView = (UIImageView *)[cell viewWithTag:100];
testImageView.image = [UIImage imageNamed:[testImages objectAtIndex:indexPath.row]];
return cell;
}
This is working and looks like this:
What I'm trying to do is to replace the locally created array from pictures that I get out of my Photo Class in Parse.
I'm trying to do this on the viewDidLoad method:
PFQuery *query = [PFQuery queryWithClassName:@"Photo"];
PFUser *user = [PFUser currentUser];
[query whereKey:@"user" equalTo:user];
[query orderByAscending:@"createdAt"];
[query setCachePolicy:kPFCachePolicyNetworkOnly];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(@"Successfully retrieved %d photos.", objects.count);
testImages = [NSMutableArray arrayWithArray:objects];
NSLog(@"# Images: %d", [testImages count]);
// Do something with the found objects
for (PFObject *object in objects) {
NSLog(@"Object Name: %@", object.objectId);
}
} else {
// Log details of the failure
NSLog(@"Error: %@ %@", error, [error userInfo]);
}
}];
The thing is that I'm getting an empty array every time. I'm guessing that since this is getting executed on the block in the background once the collectionView:numberOfItemsInSection: asks for the count of elements on the "testImages" array I always get 0 elements.
When the UICollectionViewController wants to use the information from the array to fill in the cells there's nothing there.
I don't know if I'm placing my code in the wrong place or if I'm using the wrong query.
Can you get my error here?
Any feedback would be greatly appreciated.
Upvotes: 2
Views: 1665
Reputation: 1526
finally I got something working. @gg13's feedback has been key to solve the empty array problem.
I'll leave the solution here just in case it helps anyone else some other time.
I put my query on a new method:
- (void)queryForTable
{
PFQuery *query = [PFQuery queryWithClassName:@"Photo"];
PFUser *user = [PFUser currentUser];
[query whereKey:@"user" equalTo:user];
[query orderByAscending:@"createdAt"];
[query setCachePolicy:kPFCachePolicyNetworkOnly];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(@"Successfully retrieved %d photos.", objects.count);
[self.collectionView reloadData];
gridImages = [[NSMutableArray alloc] initWithCapacity:objects.count];
// Do something with the found objects
for (PFObject *object in objects) {
PFFile *thumbnail = [object objectForKey:@"thumbnail"];
[thumbnail getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (!error) {
// Now that the data is fetched, update the cell's image property with thumbnail
NSLog(@"Fetching image..");
[gridImages addObject:[UIImage imageWithData:data]];
NSLog(@"Size of the gridImages array: %d", [gridImages count]);
} else {
// Log details of the failure
NSLog(@"Error: %@ %@", error, [error userInfo]);
}
}];
}
} else {
// Log details of the failure
NSLog(@"Error: %@ %@", error, [error userInfo]);
}
}];
}
That I'm calling on viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self queryForTable];
}
Then I changed my collectionView:cellForItemAtIndexPath: method to this:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
// Set up cell identifier that matches the Storyboard cell name
static NSString *identifier = @"Cell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
// Configure the cell to show photo thumbnail
UIImageView *imageView = (UIImageView *)[cell viewWithTag:100];
//NSLog(@"testImages: %@", [testImages objectAtIndex:indexPath.row]);
imageView.image = [UIImage imageNamed:@"placeholder.jpg"];
imageView.image = [gridImages objectAtIndex:indexPath.row];
return cell;
}
And so far it's working. The app is getting the images from Parse and it looks like this:
I still have to test a few things and specially the scenario with huge amount of images (including a progress indicator or something) but at least to get this already is a good thing.
I'm sure Parse will make their own UICollectionViewController sooner or later as they did with the UITableViewController and things will improve even more.
As said before, thanks for the feedback, I'm leaving this here just in case someone else comes into the same problem and of course open to feedback and suggestions.
Cheers,
Upvotes: 4