AssetLibrary не возвращает все активы с "ALAssetsGroupAll"

Я запрашиваю библиотеку активов с помощью следующего кода

ALAssetsLibrary *assetsLibrary = [self defaultAssetsLibrary];
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
    NSMutableArray *tmpAssets = [@[] mutableCopy];
    [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
        if(result)
        {
            [tmpAssets addObject:result];
        }
    }];

    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO];
    finished([[tmpAssets sortedArrayUsingDescriptors:@[sort]]  mutableCopy]);

} failureBlock:^(NSError *error) {
    finished(@[]);
    NSLog(@"Error loading images %@", error);
}];

Однако кажется, что я не получаю все активы, если я добавляю изображения на iPhone из внешнего источника, они не отображаются в списке активов, полученных из приведенного выше кода... Я получаю то, что кажется, как все остальное, Я подозревал, что это может быть ограничением фреймворка, но когда я использовал instagram, я заметил, что фотографии, отсутствующие в моем приложении, были видны... Как я могу получить каждый тип ресурса "ALAssetsGroupAll" недостаточно?

2 ответа

Решение

Проблема в том, что вы не понимаете, как enumerateAssetsUsingBlock: работает. Это асинхронный.

Чтобы понять, что я имею в виду, позвольте мне разделить ваш код, используя несколько чисел:

// (1)
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
    // (2)
    if(result)
    {
        [tmpAssets addObject:result];
    }
}];
// (3)
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO];
finished([[tmpAssets sortedArrayUsingDescriptors:@[sort]]  mutableCopy]);

Проблема в том, что 3 выполняется до 2. Таким образом, нет ничего в tmpAssets еще.

Так что ты должен делать с этим? Ну, этот метод (и другие методы ALAssets, которые работают аналогично) работают очень странным и особым образом: они вызывают свой блок один раз, с аргументом nil. (Похоже, вы поняли это, так как вы проводите нулевой тест; но вы не поняли, каковы последствия.) Ваша задача - проверить нулевой параметр. Если параметр равен nil, это последний дополнительный вызов, и теперь вы можете выполнить любую очистку. Ну вот так:

// (1)
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
    // (2)
    if(result)
    {
        [tmpAssets addObject:result];
    }
    else
    // (3) // aha, finished, this is the extra time through
    {
        // NOW do something with tmpAssets!
    }
}];

Похоже, вам нужно добавить все активы в один массив из всех групп, а не для групп по отдельности с несколькими вызовами в готовый блок.

-(NSArray *)allAssets {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    NSMutableArray *allAssets = [@[] mutableCopy];

    [[self defaultAssetsLibrary] enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
            if(result)
                [tmpAssets addObject:result];
        }];

        dispatch_semaphore_signal(semaphore);
    } failureBlock:^(NSError *error) {
        NSLog(@"Error loading images %@", error);
        dispatch_semaphore_signal(semaphore);
    }];

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO];
    return [tmpAssets sortedArrayUsingDescriptors:@[sort]];
}
Другие вопросы по тегам