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