2012-11-08 99 views
1

我想挑出一些相機膠捲元數據。當我列舉資產時,似乎無法檢索任何信息並獲得空數組。我錯過了一個步驟嗎?AlAssetLibrary返回空結果

我的代碼:

assets = [[NSMutableArray array] init]; 

void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *asset, NSUInteger index, BOOL *stop) { 
    if(asset != NULL) { 
     [assets addObject:asset]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
     }); 
    } 
}; 

void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) { 
    if(group != nil) { 
     [group enumerateAssetsUsingBlock:assetEnumerator]; 
    } 
}; 

library = [[ALAssetsLibrary alloc] init]; 

[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos 
         usingBlock:assetGroupEnumerator 
        failureBlock: ^(NSError *error) { 
         NSLog(@"Failed."); 
        }];  

NSLog(@"%@", assets); //prints an empty array 
+0

感謝您的回答。還有一個問題 - 是否有一種簡單的方法可以挑選在某一日期拍攝的照片,而無需列舉所有資產? – HHHH

回答

4

Midhun MP是正確的,你不等待異步枚舉完成。在這種情況下,您有異步塊調用其他異步塊,因此知道何時完成所有枚舉並不容易。

如果您想知道何時完成此操作,並最終獲得一個包含所有枚舉資產的數組,您可以使用dispatch_groups。這裏是你能做到這一點的一種方式(我已經包含多個ALAssetGroup類型表明,這可以用多個相冊工作):

dispatch_group_t loadingGroup = dispatch_group_create(); 
NSMutableArray * assets = [[NSMutableArray array] init]; 
NSMutableArray * albums = [[NSMutableArray array] init]; 

void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *asset, NSUInteger index, BOOL *stop) { 
    if(index != NSNotFound) { 
     [assets addObject:asset]; 
     dispatch_async(dispatch_get_main_queue(), ^{ }); 
    } else { 
     dispatch_group_leave(loadingGroup); 
    } 
}; 


void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) { 
    if(group != nil) { 
     [albums addObject: group]; 
    } else { 
     NSLog(@"Found %d albums", [albums count]); 
     // album loading is done 
     for (ALAssetsGroup * album in albums) { 
      dispatch_group_enter(loadingGroup); 
      [album enumerateAssetsUsingBlock: assetEnumerator]; 
     } 
     dispatch_group_notify(loadingGroup, dispatch_get_main_queue(), ^{ 
      NSLog(@"DONE: ALAsset array contains %d elements", [assets count]); 
     }); 
    } 
}; 

ALAssetsLibrary * library = [[ALAssetsLibrary alloc] init]; 

[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos | ALAssetsGroupAlbum 
        usingBlock:assetGroupEnumerator 
       failureBlock: ^(NSError *error) { 
        NSLog(@"Failed."); 
       }]; 

(在這個例子中,它是安全的,有不同的塊加入assetsalbums因爲枚舉全部發生在主線程上。)

+0

很難挑出一個正確的答案,因爲所有人都指出我的問題,但這是最全面的。謝謝! – HHHH

+0

使用** assetEnumerator **枚舉資產時,是否應該同步訪問**資產**數組。 像'@synchronized(self){[assets addObject:asset]; }' – OnTheEasiestWay

+0

3年後,這篇文章救了我,謝謝! – MarioAna

0

如果您在iOS 6上運行此,這可能是因爲用戶已經拒絕訪問你的應用程序來訪問資源庫。如果是這種情況,則調用failureBlock

另請注意,usingBlock是異步調用的,因此您嘗試記錄assets爲時尚早。您應該將NSLog語句移動到枚舉塊的末尾。

從文檔爲enumerateGroupsWithTypes:usingBlock:failureBlock:

結果通過執行枚舉塊通過一個接一個地給調用者。

此方法是異步的。枚舉組時,可能會要求用戶確認應用程序對數據的訪問權限;該方法雖然立即返回。您應該使用enumerationBlock中的資產執行任何您想要的工作。

如果用戶拒絕訪問應用程序,或者沒有應用程序被允許訪問數據,則調用failureBlock。

0

您的NSLog將始終顯示一個空數組,因爲在完成異步枚舉塊之前NSLog語句將工作。

解決方案:

首先檢查你的photolibrary不是空的。 然後在添加的NSLog:

void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *asset, NSUInteger index, BOOL *stop) { 
    if(asset != NULL) { 
     [assets addObject:asset]; 
     NSLog(@"Asset : %@", asset); 
     dispatch_async(dispatch_get_main_queue(), ^{ 
     }); 
    } 
};