Photo Frameworks之PHAssetCollection、PHCollectionList和PHAsset

該框架在圖片app中用來管理圖片和音視頻文件,用來一部查找和緩存資源或者縮略圖、修復(fù)內(nèi)容和在不同設(shè)備間同步圖片等資源。
先簡單的了解一些概念:

  • PHAsset:單個資源
  • PHAssetCollection:PHCollection的子類,單個資源的集合,如相冊、時刻等
  • PHCollectionList:PHCollection的子類,集合的集合,如相冊文件夾
  • PHPhotoLibrary:類似于總管理,負責(zé)注冊通知、檢查和請求獲取權(quán)限
  • PHImageManager:按照要求獲取制定的圖片
  • PHCachingImageManager:PHImageManager的子類
  • PHAssetChangeRequest:編輯相冊,增刪改查
下面一一做盡可能詳盡的說明

*PHCollection

在進行下面的實驗之前,先簡單的說說該類中的一個方法:
+ (PHFetchResult<PHCollection *> *)fetchTopLevelUserCollectionsWithOptions:(nullable PHFetchOptions *)options;
該方法用來獲取處于圖片app中根目錄下的自己創(chuàng)建的相冊(貌似自己創(chuàng)建的本身就在根目錄下)

1、PHAssetCollection

一個該實例對象代表一個相冊。是PHCollection的子類。
它的所有屬性都是只讀的,另外有8個類方法,用來獲取想要的結(jié)果。

  • + (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsWithType:(PHAssetCollectionType)type subtype:(PHAssetCollectionSubtype)subtype options:(nullable PHFetchOptions *)options;
    該方法是該類的主要訪問方法,主要用于在未知相冊的情況下,直接通過type和subtype從相冊獲取相應(yīng)的相冊。type和subtype如下所示:
typedef NS_ENUM(NSInteger, PHAssetCollectionType) {
 PHAssetCollectionTypeAlbum      = 1,  相冊,系統(tǒng)外的
 PHAssetCollectionTypeSmartAlbum = 2,  智能相冊,系統(tǒng)自己分配和歸納的
 PHAssetCollectionTypeMoment     = 3,  時刻,系統(tǒng)自動通過時間和地點生成的分組
 } PHOTOS_ENUM_AVAILABLE_IOS_TVOS(8_0, 10_0);
 *
 * typedef NS_ENUM(NSInteger, PHAssetCollectionSubtype) {
 
 // PHAssetCollectionTypeAlbum regular subtypes
 PHAssetCollectionSubtypeAlbumRegular         = 2, // 在iPhone中自己創(chuàng)建的相冊
 PHAssetCollectionSubtypeAlbumSyncedEvent     = 3, // 從iPhoto(就是現(xiàn)在的圖片app)中導(dǎo)入圖片到設(shè)備
 PHAssetCollectionSubtypeAlbumSyncedFaces     = 4, // 從圖片app中導(dǎo)入的人物照片
 PHAssetCollectionSubtypeAlbumSyncedAlbum     = 5, // 從圖片app導(dǎo)入的相冊
 PHAssetCollectionSubtypeAlbumImported        = 6, // 從其他的相機或者存儲設(shè)備導(dǎo)入的相冊
 
 // PHAssetCollectionTypeAlbum shared subtypes
 PHAssetCollectionSubtypeAlbumMyPhotoStream   = 100,  // 照片流,照片流和iCloud有關(guān),如果在設(shè)置里關(guān)閉了iCloud開關(guān),就獲取不到了
 PHAssetCollectionSubtypeAlbumCloudShared     = 101,  // iCloud的共享相冊,點擊照片上的共享tab創(chuàng)建后就能拿到了,但是前提是你要在設(shè)置中打開iCloud的共享開關(guān)(打開后才能看見共享tab)
 
 // PHAssetCollectionTypeSmartAlbum subtypes
 PHAssetCollectionSubtypeSmartAlbumGeneric    = 200,
 PHAssetCollectionSubtypeSmartAlbumPanoramas  = 201,  // 全景圖、全景照片
 PHAssetCollectionSubtypeSmartAlbumVideos     = 202,  // 視頻
 PHAssetCollectionSubtypeSmartAlbumFavorites  = 203,  // 標記為喜歡、收藏
 PHAssetCollectionSubtypeSmartAlbumTimelapses = 204,  // 延時拍攝、定時拍攝
 PHAssetCollectionSubtypeSmartAlbumAllHidden  = 205,  // 隱藏的
 PHAssetCollectionSubtypeSmartAlbumRecentlyAdded = 206,  // 最近添加的、近期添加
 PHAssetCollectionSubtypeSmartAlbumBursts     = 207,  // 連拍
 PHAssetCollectionSubtypeSmartAlbumSlomoVideos = 208,  // Slow Motion,高速攝影慢動作(概念不懂)
 PHAssetCollectionSubtypeSmartAlbumUserLibrary = 209,  // 相機膠卷
 PHAssetCollectionSubtypeSmartAlbumSelfPortraits PHOTOS_AVAILABLE_IOS_TVOS(9_0, 10_0) = 210, // 使用前置攝像頭拍攝的作品
 PHAssetCollectionSubtypeSmartAlbumScreenshots PHOTOS_AVAILABLE_IOS_TVOS(9_0, 10_0) = 211,  // 屏幕截圖
 PHAssetCollectionSubtypeSmartAlbumDepthEffect PHOTOS_AVAILABLE_IOS_TVOS(10_2, 10_1) = 212,  // 在可兼容的設(shè)備上使用景深攝像模式拍的照片(概念不懂)
 PHAssetCollectionSubtypeSmartAlbumLivePhotos PHOTOS_AVAILABLE_IOS_TVOS(10_3, 10_2) = 213,  // Live Photo資源
 PHAssetCollectionSubtypeSmartAlbumAnimated PHOTOS_AVAILABLE_IOS_TVOS(11_0, 11_0) = 214,  // 沒有解釋
 PHAssetCollectionSubtypeSmartAlbumLongExposures PHOTOS_AVAILABLE_IOS_TVOS(11_0, 11_0) = 215,  // 沒有解釋
 // Used for fetching, if you don't care about the exact subtype
 PHAssetCollectionSubtypeAny = NSIntegerMax
 } PHOTOS_ENUM_AVAILABLE_IOS_TVOS(8_0, 10_0);
  • + (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsWithLocalIdentifiers:(NSArray<NSString *> *)identifiers options:(nullable PHFetchOptions *)options;
    通過identifier的數(shù)組來查找到相應(yīng)的資源,不過這里的identifier應(yīng)使用上面的方法獲取到相冊后拿到的相冊的identifier(根據(jù)屬性localIdentifier即可獲取到),否則會得到意想不到的結(jié)果。測試代碼如下:
- (IBAction)fetchCollectionWithIdentifier:(id)sender {
    // 先試試用圖片的identifier
    NSMutableArray * assetIdentifierArr = [NSMutableArray array];
    NSMutableArray * identifierArr = [NSMutableArray array];
    PHFetchResult<PHAssetCollection *> * result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    [result enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (obj.localIdentifier.length > 0) {
            NSLog(@"%@--%@", obj.localIdentifier, obj.localizedTitle);
            [identifierArr addObject:obj.localIdentifier];
            PHFetchResult<PHAsset *> * assetResult = [PHAsset fetchAssetsInAssetCollection:obj options:nil];
            PHAsset * asset = assetResult.firstObject;
            [assetIdentifierArr addObject:asset.localIdentifier];
        }
    }];
    // 注意:這里使用的是單個資源的identifier
    PHFetchResult<PHAssetCollection *> * assetIdentifierResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:assetIdentifierArr options:nil];
    [assetIdentifierResult enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (obj.localIdentifier.length > 0) {
            NSLog(@"%@", obj);
        }
    }];
    NSLog(@"================================");
// 注意:這里使用的是相冊的identifier
    PHFetchResult<PHAssetCollection *> * identifierResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:identifierArr options:nil];
    [identifierResult enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (obj.localIdentifier.length > 0) {
            NSLog(@"%@", obj);
        }
    }];
}

可以先預(yù)想一下結(jié)果,然后再看下面的截圖:
image.png

上面的使用也再一次的證明了identifier一定要使用代碼獲取到的才行。

  • + (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsContainingAsset:(PHAsset *)asset withType:(PHAssetCollectionType)type options:(nullable PHFetchOptions *)options;
    查找包含資源asset的相冊
  • + (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsWithALAssetGroupURLs:(NSArray<NSURL *> *)assetGroupURLs options:(nullable PHFetchOptions *)options;
    舊版的圖片框架和新版框架的交互,不過到了今天,已經(jīng)基本上不用考慮該方法的調(diào)用了。
  • + (PHFetchResult<PHAssetCollection *> *)fetchMomentsInMomentList:(PHCollectionList *)momentList options:(nullable PHFetchOptions *)options;
  • + (PHFetchResult<PHAssetCollection *> *)fetchMomentsWithOptions:(nullable PHFetchOptions *)options;
    上面的兩個方法是獲取Moment相冊的簡單方法
  • + (PHAssetCollection *)transientAssetCollectionWithAssets:(NSArray<PHAsset *> *)assets title:(nullable NSString *)title;
  • + (PHAssetCollection *)transientAssetCollectionWithAssetFetchResult:(PHFetchResult<PHAsset *> *)fetchResult title:(nullable NSString *)title;
    利用已知資源創(chuàng)建一個新的集合或者說相冊,但是該相冊不會被永久存儲下來。具體的使用后面再說吧。

2、PHCollectionList

該類用來表示集合的集合。但是我并沒有發(fā)現(xiàn)怎么創(chuàng)建出該現(xiàn)象。而如果不創(chuàng)建(假如可以創(chuàng)建但是沒創(chuàng)建)時,在實際的調(diào)用中,得到的結(jié)果和預(yù)想的也不一樣,有些困惑,所以,這一節(jié)暫時先放放吧。

3、PHAsset

該類表示具體的資源信息,如寬度、高度、時長、是否是收藏的等等。同上面提到的幾個類一樣,該類的屬性也都是只讀的,所以我們主要是用它的方法來獲取資源。

  • - (BOOL)canPerformEditOperation:(PHAssetEditOperation)editOperation;
    用來判斷該資源是否可以做某些操作,比如增刪改查。也從另一個方面暗示了,在對該資源做一些操作之前有必要先做一下判斷,這可以省去一些不必要的麻煩。
  • + (PHFetchResult<PHAsset *> *)fetchAssetsInAssetCollection:(PHAssetCollection *)assetCollection options:(nullable PHFetchOptions *)options;
    該方法是從相冊中獲取單個資源的主要途徑:
- (IBAction)useToFetchCollection:(id)sender {
    // 先獲取到集合
    PHFetchResult<PHAssetCollection *> * collectionResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumFavorites options:nil];
    if (collectionResult.count == 0) {
        return;
    }
    // 遍歷集合,獲取信息
    [collectionResult enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        PHFetchResult<PHAsset *> * assetResult = [PHAsset fetchAssetsInAssetCollection:obj options:nil];
        NSLog(@"%@", assetResult);
    }];
}
  • + (PHFetchResult<PHAsset *> *)fetchAssetsWithLocalIdentifiers:(NSArray<NSString *> *)identifiers options:(nullable PHFetchOptions *)options;
    該方法的使用和PHAssetCollection的相同,是個查找功能;如果identifier是隱藏的資源,默認是會被找到的,如果不想找到隱藏的,可以通過options的屬性includeHiddenAssets來設(shè)置(貌似沒什么用)。
  • + (PHFetchResult<PHAsset *> *)fetchAssetsWithBurstIdentifier:(NSString *)burstIdentifier options:(nullable PHFetchOptions *)options;
    根據(jù)identifier獲取連拍資源,如果傳遞的identifier不是連拍資源的identifier,即使相冊里有匹配的資源,也不會返回。不過蘋果官方說明:默認只會獲取一些具有代表性的,如果想獲取全部的連拍資源,需要在options里做處理。
  • + (PHFetchResult<PHAsset *> *)fetchAssetsWithOptions:(nullable PHFetchOptions *)options;
    在相機膠卷中根據(jù)options來獲取合適的資源
  • + (PHFetchResult<PHAsset *> *)fetchAssetsWithMediaType:(PHAssetMediaType)mediaType options:(nullable PHFetchOptions *)options;
    在相機膠卷中根據(jù)mediaType媒體類型和options獲取匹配的資源
  • + (nullable PHFetchResult<PHAsset *> *)fetchKeyAssetsInAssetCollection:(PHAssetCollection *)assetCollection options:(nullable PHFetchOptions *)options;
    獲取相冊資源的封面圖,根據(jù)相冊類型的不同,返回的資源封面的個數(shù)也不同。
    如果是零時的相冊,是沒有封面的。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容