Анализирайте заявка във ViewDidLoad за UICollectionViewController

Опитвам се да адаптирам използването на UICollectionViewController, който попълвам с масив от локални изображения, за да получа изображенията от Parse.

Дотук е доста ясно. Моят NSArray се запълва с едно и също локално изображение много пъти:

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", нула];

В collectionView:cellForItemAtIndexPath: настройвам клетката си (от 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;
}

Това работи и изглежда така:

UICollectionViewController с масив от локални изображения

Това, което се опитвам да направя, е да заменя локално създадения масив от снимки, които получавам от моя Photo Class в Parse.

Опитвам се да направя това с метода viewDidLoad:

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

Работата е там, че всеки път получавам празен масив. Предполагам, че тъй като това се изпълнява в блока във фонов режим, след като collectionView:numberOfItemsInSection: поиска броя на елементите в масива "testImages", винаги получавам 0 елемента.

Когато UICollectionViewController иска да използва информацията от масива, за да попълни клетките, там няма нищо.

Не знам дали поставям кода си на грешното място или използвам грешна заявка.

Можете ли да разберете грешката ми тук?

Всякакви отзиви ще бъдат много оценени.


person Juan González    schedule 04.07.2013    source източник
comment
В блока за завършване извикването на метода reloadData на вашия collectionView ще попълни клетките. Не съм сигурен, че това е отговорът, който търсите, но ще свърши работа   -  person gg13    schedule 05.07.2013
comment
Здравей @gg13, това се получи, благодаря, но изглежда малко странно. Отпечатвам броя на извлечените обекти (с NSLog) и първо получавам 0, след това след reloadData получавам правилното количество. Това редовен начин ли е за работа с UICollectionViewController? Изглежда странно, въпреки че трябва да призная, че все още не съм експерт.   -  person Juan González    schedule 05.07.2013
comment
Това, което се случва, е, че когато за първи път отпечатвате броя на извлечените обекти, Parse не е завършил заявката за обектите, така че връща 0. По същия начин изгледът на колекцията се опитва да се настрои с празен масив, поради което не получавате нищо. След това, тъй като извиквате reloadData в блока за завършване, заявката е завършена, така че имате своите обекти и изгледът на колекцията може да се попълни сам. Това наистина не е нищо по-различно от UITableView, тъй като те не биха могли да се попълнят без никакви обекти.   -  person gg13    schedule 06.07.2013


Отговори (1)


най-накрая имам нещо работещо. Обратната връзка на @gg13 беше ключова за решаването на проблема с празния масив.

Ще оставя решението тук, в случай че помогне на някой друг друг път.

Зададох запитването си на нов метод:

- (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]);
        }
    }];
}

Това, което викам на viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    [self queryForTable];
}

След това промених моя метод collectionView:cellForItemAtIndexPath: на това:

- (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;
}

И засега работи. Приложението получава изображенията от Parse и изглежда така:

UICollectionViewController с разбор на изображения

Все още трябва да тествам няколко неща и по-специално сценария с огромно количество изображения (включително индикатор за напредък или нещо подобно), но поне да го получа вече е хубаво нещо.

Сигурен съм, че Parse ще направят свой собствен UICollectionViewController рано или късно, както направиха с UITableViewController и нещата ще се подобрят още повече.

Както казах преди, благодаря за обратната връзка, оставям това тук, в случай че някой друг се сблъска със същия проблем и, разбира се, отворен за обратна връзка и предложения.

наздраве,

person Juan González    schedule 06.07.2013