PHAssetCollection我習(xí)慣稱之為相冊,在上一節(jié)主要總結(jié)和學(xué)習(xí)了對PHAsset的使用,有了上一節(jié)的基礎(chǔ),這一節(jié)并不難。
對PHAsset的操作主要涉及的類是PHAssetChangeRequest和它的子類PHAssetCreationRequest。同樣的,對于相冊的操作也有一個專門的類:PHAssetCollectionChangeRequest。
不過雖然說是創(chuàng)建相冊,但是其實你并沒有權(quán)限直接向創(chuàng)建的相冊添加或者更新新的原本在相冊中不存在的資源,而只是把原來的相冊中的資源做了重新歸納和調(diào)整而已,如果想添加不存在的資源,還是得用PHAssetChangeRequest。
記得在之前曾經(jīng)探討過,發(fā)現(xiàn)所有的各種類型的相冊中,都允許被永久刪除單一asset,除此之外,系統(tǒng)自帶的和同步過來的相冊都不用許做其他的操作,只有自己創(chuàng)建的相冊才被允許在相冊層面對資源做增刪改的操作。
PHAssetCollectionChangeRequest
和PHAssetChangeRequest一樣,相關(guān)的操作都需要放到PHPhotoLibrary的perform的block中。
- 創(chuàng)建相冊
- (IBAction)toCreateAssetCollection:(id)sender {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest * request = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"相冊"];
NSLog(@"identifier:%@", request.placeholderForCreatedAssetCollection.localIdentifier); //獲取創(chuàng)建的相冊的永久的唯一identifier
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
[self showDetailInfo:@"創(chuàng)建成功"];
} else {
[self showDetailInfo:@"創(chuàng)建失敗"];
}
}];
}
如上,直接調(diào)用方法creationRequestForAssetCollectionWithTitle
即可創(chuàng)建相冊,同時,可以通過placeholderForCreatedAssetCollection可以獲取到創(chuàng)建的相冊的identifier。
這里需要指出的是創(chuàng)建的相冊名字是可以重復(fù)的。
- 刪除相冊
主要的方法是+ (void)deleteAssetCollections:(id<NSFastEnumeration>)assetCollections;
;所以首先要獲取到要刪除的相冊,但是需要明確的一點(diǎn)是,必須判斷是否有權(quán)限去刪除該相冊。這里的assetCollections是asset collection的集合,但是該集合需要遵守協(xié)議NSFastEnumeration。
- (IBAction)toDeleteAssetCollection:(id)sender {
// 先獲取需要刪除的相冊,其實能刪除的也就只有自己創(chuàng)建的相冊而已
NSMutableArray<PHAssetCollection *> * delArr = [NSMutableArray array];
PHFetchResult<PHAssetCollection *> * result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil];
[result enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj canPerformEditOperation:PHCollectionEditOperationDelete]) { // 判斷是否有權(quán)限刪除
[delArr addObject:obj];
}
}];
if (delArr.count == 0) {
[self showDetailInfo:@"No thing to delete!"];
return;
}
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetCollectionChangeRequest deleteAssetCollections:delArr];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
[self showDetailInfo:@"刪除成功"];
} else {
[self showDetailInfo:@"刪除失敗"];
}
}];
}
- 更新相冊
更新相冊有兩種方法:
+ (nullable instancetype)changeRequestForAssetCollection:(PHAssetCollection *)assetCollection;
+ (nullable instancetype)changeRequestForAssetCollection:(PHAssetCollection *)assetCollection assets:(PHFetchResult<PHAsset *> *)assets;
實例如下:
- (IBAction)toModifyAssetCollectionWithoutIndexes:(id)sender {
// 測試其他相冊是否可以從其他相冊添加內(nèi)容,這里測試SmartAlbum,你會發(fā)現(xiàn)下面打印了一系列的不能添加
PHFetchResult<PHAssetCollection *> * smartCollection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAny options:nil];
[smartCollection enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj canPerformEditOperation:PHCollectionEditOperationAddContent]) {
NSLog(@"可以添加");
} else {
NSLog(@"不能添加");
}
}];
PHFetchResult<PHAssetCollection *> * result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
if (result.count == 0) {
[self showDetailInfo:@"沒有可以修改的相冊"];
return;
}
// 添加
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// 獲取assets
PHFetchResult<PHAssetCollection *> * fetchCollection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil];
PHFetchResult<PHAsset *> * fetchAssets = [PHAsset fetchAssetsInAssetCollection:fetchCollection.firstObject options:nil];
PHAssetCollectionChangeRequest * request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:result.firstObject];
[request addAssets:fetchAssets];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
[self showDetailInfo:@"修改成功"];
} else {
[self showDetailInfo:@"修改失敗"];
}
}];
}
- (IBAction)toModifyAssetCollectionWithIndexes:(id)sender {
PHFetchResult<PHAssetCollection *> * result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
if (result.count == 0) {
[self showDetailInfo:@"沒有可以修改的相冊"];
return;
}
// 添加
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// 獲取assets
PHFetchResult<PHAssetCollection *> * fetchCollection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumFavorites options:nil];
PHFetchResult<PHAsset *> * fetchAssets = [PHAsset fetchAssetsInAssetCollection:fetchCollection.firstObject options:nil];
// asset必須為當(dāng)前collection里的,如果沒有調(diào)用changeRequestForAssetCollection方法,都可以
PHAssetCollectionChangeRequest * request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:result.firstObject assets:[PHAsset fetchAssetsInAssetCollection:result.firstObject options:nil]];
NSMutableIndexSet * mutableIndexSet = [NSMutableIndexSet indexSet];
for (NSInteger i = 1; i <= fetchAssets.count; i++) {
[mutableIndexSet addIndex:i];
}
// 這里的index表示在相冊中的位置;要保證indexes的長度為assets的長度;indexes里的值不能超過合并后的相冊的個數(shù)
[request insertAssets:fetchAssets atIndexes:mutableIndexSet];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
[self showDetailInfo:@"修改成功"];
} else {
[self showDetailInfo:@"修改失敗"];
}
}];
}
這里著重記錄一下帶assets的更新,蘋果文檔里說,如果使用index,則應(yīng)該使用該方法,但是我實驗發(fā)現(xiàn),即使這里不使用帶assets的方法也可以正常操作。
另外這里的參數(shù)indexes,首先要保證其中包含的個數(shù)和要操作的asset相同;其次里面的值不允許越界,即里面出現(xiàn)的值不能超出要修改的相冊里的資源的總數(shù),否則程序會崩潰。
最后,indexes里的值表示對應(yīng)assets的位置。
還有其他的幾個更新相冊的方法,可以自己去實驗,大都和這里差不多。
至此,相冊的增刪改查也告一段落!