iOS獲取相冊資源

image.png

Photokit介紹

1,基類 PHObject

Photos 框架中的根類PHObject只有一個公開接口 localIdentifier,是對象唯一標(biāo)志符.PHObject實(shí)現(xiàn)了-isEqual 和-hash方法.可以直接使用localIdentifier屬性對PHObject及其子類對象進(jìn)行對比是否同一個對象

2,數(shù)據(jù)類型

PHAsset 回论、PHAssetCollection派哲、PHCollectionList 是Photos框架中的模型類

PHAsset :代表系統(tǒng)的一個圖片帮碰,視頻或者Live Photo
PHAssetCollection:是一組有序的資源集合,包括相冊浑彰、moments、智能相冊以及共享照片流.比如:系統(tǒng)相冊里的時(shí)刻一個分類抹蚀,用戶創(chuàng)建的相冊或者智能相冊
PHCollectionList : 相冊集合, 比如:時(shí)刻里的年或者包含用戶創(chuàng)建的一個或者多個相冊
表示一組PHCollection,而它本身也是一個PHCollection,因此PHCollection作為一個集合剿牺,可以包含其他集合
如下資源結(jié)構(gòu)圖:

image
2.1 PHAsset.h
2.1.1 PHAsset

代表系統(tǒng)的一個圖片,視頻或者Live Photo
屬性介紹:

[1] mediaType :資源類型,圖片或者音頻或視頻
 PHAssetMediaTypeUnknown = 0,
 PHAssetMediaTypeImage   = 1,
 PHAssetMediaTypeVideo   = 2,
 PHAssetMediaTypeAudio   = 3,

 [2] mediaSubtypes
 圖片又包含全景圖(Panorama)环壤、HDR圖片晒来、屏幕截圖、livePhoto .live photo 加3Dtouch效果 我們可以使用照片資源的 mediaSubtypes 屬性驗(yàn)證資源庫中的圖像在捕捉時(shí)是否開啟了 HDR郑现,拍攝時(shí)是否使用了相機(jī)應(yīng)用的全景模式

 PHAssetMediaSubtypeNone      = 0,

 // Photo subtypes
 PHAssetMediaSubtypePhotoPanorama
 PHAssetMediaSubtypePhotoHDR
 PHAssetMediaSubtypePhotoScreenshot
 PHAssetMediaSubtypePhotoLive
 PHAssetMediaSubtypePhotoDepthEffect

 // Video subtypes
 PHAssetMediaSubtypeVideoStreamed      = (1UL << 16),
 PHAssetMediaSubtypeVideoHighFrameRate = (1UL << 17),
 PHAssetMediaSubtypeVideoTimelapse

 [3] pixelWidth 像素寬度 pixelHeight 高度

 [4] creationDate 創(chuàng)建時(shí)間   modificationDate 修改時(shí)間  location 位置信息 duration時(shí)長

 [5] hidden 要驗(yàn)證一個資源是否被用戶標(biāo)記為收被隱藏湃崩,只要檢查 PHAsset 實(shí)例的 hidden 屬性即可。
 [6] Favorite  布爾值接箫,用戶是否標(biāo)記資源為"收藏"攒读,我們平時(shí)瀏覽照片或視頻,在下方點(diǎn)??就表示收藏這張圖

 [7] representsBurst 和 burstSelectionTypes: 對于一個資源辛友,如果其 PHAsset 的 representsBurst 屬性為 true整陌,則表示這個資源是一系列連拍照片中的代表照片 (多張照片是在用戶按住快門時(shí)拍攝的)。它還有一個屬性是 burstIdentifier,如果想要獲取連拍照片中的剩余的其他照片泌辫,可以通過將這個值傳入 fetchAssetsWithBurstIdentifier(...) 方法來獲取。用戶可以在連拍的照片中做標(biāo)記九默;此外震放,系統(tǒng)也會自動用各種試探來標(biāo)記用戶可能會選擇的潛在代表照片。這個元數(shù)據(jù)是可以通過 PHAsset 的 burstSelectionTypes 屬性來訪問驼修。這個屬性是用三個常量組成的位掩碼:.UserPick 表示用戶手動標(biāo)記的資源殿遂,.AutoPick 表示用戶可能標(biāo)記的潛在資源,.None 表示沒有標(biāo)記的資源

 [8] localIdentifier Photos 框架中的根類PHObject只有一個公開接口localIdentifier,是對象唯一唯一標(biāo)志符.PHObject實(shí)現(xiàn)了-isEqual 和-hash方法.可以直接使用localIdentifier屬性對PHObject及其子類對象進(jìn)行對比是否同一個對象

 方法
 // 可執(zhí)行編輯操作
 - (BOOL)canPerformEditOperation:(PHAssetEditOperation)editOperation;
常見的獲取資源的方法
// 獲取所有的資源  options是獲取資源的條件下文介紹
+ (PHFetchResult<PHAsset *> *)fetchAssetsWithOptions:(nullable PHFetchOptions *)options;  
// 從相冊中獲取資源 , assetCollection 可以傳入相冊的對象
 + (PHFetchResult<PHAsset *> *)fetchAssetsInAssetCollection:(PHAssetCollection *)assetCollection options:(nullable PHFetchOptions *)options; 

2.2 PHCollection.h
2.2.1, PHCollection :一個抽象類乙各,是PHAssetCollection和PHColletionList的父類

屬性:

[1.1]  localizedTitle 相冊的標(biāo)題
// 獲取資源的方法
+ (PHFetchResult<PHCollection *> *)fetchCollectionsInCollectionList:(PHCollectionList *)collectionList options:(nullable PHFetchOptions *)options;

2.2.2 , PHAssetCollection 相冊(PHAsset集合)

PHAssetCollection是一組有序的資源集合,包括相冊墨礁、moments、智能相冊以及共享照片流.比如:系統(tǒng)相冊里的時(shí)刻一個分類耳峦,用戶創(chuàng)建的相冊或者智能相冊
屬性:

[2.1] assetCollectionType  指定資源集合類型來源恩静,比如相冊或者“時(shí)刻”相冊
 PHAssetCollectionTypeAlbum      = 1,      // 用戶相冊
 PHAssetCollectionTypeSmartAlbum = 2,  // 智能相冊
 PHAssetCollectionTypeMoment     = 3,     // 時(shí)刻”相冊

 [2.2] assetCollectionSubtype 子類型
 enum PHAssetCollectionType : Int {
 case Album             //從 iTunes 同步來的相冊,以及用戶在 Photos 中自己建立的相冊
 case SmartAlbum    //經(jīng)由相機(jī)得來的相冊
 case Moment            //Photos 為我們自動生成的時(shí)間分組的相冊
 }

 enum PHAssetCollectionSubtype : Int
 {
 PHAssetCollectionSubtypeSmartAlbumSlomoVideos
 PHAssetCollectionSubtypeSmartAlbumSelfPortraits
 PHAssetCollectionSubtypeSmartAlbumScreenshots
 PHAssetCollectionSubtypeSmartAlbumDepthEffect
 PHAssetCollectionSubtypeSmartAlbumLivePhotos
 // Used for fetching, if you don't care about the exact subtype
 PHAssetCollectionSubtypeAny = NSIntegerMax

 case PHAssetCollectionSubtypeAlbumRegular              //用戶在 Photos 中創(chuàng)建的相冊
 case PHAssetCollectionSubtypeAlbumSyncedEvent      //使用 iTunes 從 Photos 照片庫或者 iPhoto 照片庫同步過來的事件蹲坷。然而驶乾,在iTunes 12 以及iOS 9.0 beta4上,選用該類型沒法獲取同步的事件相冊循签,而必須使用AlbumSyncedAlbum级乐。
 case PHAssetCollectionSubtypeAlbumSyncedFaces      //使用 iTunes 從 Photos 照片庫或者 iPhoto 照片庫同步的人物相冊。
 case PHAssetCollectionSubtypeAlbumSyncedAlbum          //從iPhoto同步到設(shè)備的相冊
 case PHAssetCollectionSubtypeAlbumImported                 //從相機(jī)或是外部存儲導(dǎo)入的相冊县匠,完全沒有這方面的使用經(jīng)驗(yàn)风科,沒法驗(yàn)證。

 case PHAssetCollectionSubtypeAlbumMyPhotoStream    //用戶的 iCloud 照片流
 case PHAssetCollectionSubtypeAlbumCloudShared          //用戶使用 iCloud 共享的相冊
 case PHAssetCollectionSubtypeSmartAlbumGeneric        //文檔解釋為非特殊類型的相冊乞旦,主要包括從 iPhoto 同步過來的相冊贼穆。
 case PHAssetCollectionSubtypeSmartAlbumPanoramas   //相機(jī)拍攝的全景照片
 case PHAssetCollectionSubtypeSmartAlbumVideos          //相機(jī)拍攝的視頻
 case PHAssetCollectionSubtypeSmartAlbumFavorites       //收藏文件夾
 case PHAssetCollectionSubtypeSmartAlbumTimelapses      //延時(shí)視頻文件夾,同時(shí)也會出現(xiàn)在視頻文件夾中
 case PHAssetCollectionSubtypeSmartAlbumAllHidden       //包含隱藏照片或視頻的文件夾
 case PHAssetCollectionSubtypeSmartAlbumRecentlyAdded //相機(jī)近期拍攝的照片或視頻
 case PHAssetCollectionSubtypeSmartAlbumBursts                  //連拍模式拍攝的照片
 case PHAssetCollectionSubtypeSmartAlbumUserLibrary  //這個命名最神奇了杆查,就是相機(jī)相冊扮惦,所有相機(jī)拍攝的照片或視頻都會出現(xiàn)在該相冊中,而且使用其他應(yīng)用保存的照片也會出現(xiàn)在這里,用戶創(chuàng)建出來的
 case Any //包含所有類型
 }

 [2.3] startDate endDate 開始 結(jié)束時(shí)間

 [2.4] estimatedAssetCount :估算的asset數(shù)量亲桦,不精確

 [2.5] CLLocation *approximateLocation;  大概的位置
 [2.6] NSArray<NSString *> *localizedLocationNames; 位置地區(qū)的名字?jǐn)?shù)組

2.2.3 , PHCollectionList : 相冊集合

表示一組PHCollection,而它本身也是一個PHCollection,因此PHCollection作為一個集合崖蜜,可以包含其他集合
屬性:

 [3.1] collectionListType
 [3.2] collectionListSubtype
 [3.3] startDate
 [3.4 ] endDate

獲取模型數(shù)據(jù)
PHAsset 、PHCollection客峭、PHCollectionList有一系列類方法可供我們訪問資源的元數(shù)據(jù)

 1, 比如PHAsset提供了一系列獲取PHAsset對象的方法
 + fetchAssetsInAssetCollection:options:
 + fetchAssetsWithMediaType:options:
 + fetchAssetsWithLocalIdentifiers:options:
 + fetchKeyAssetsInAssetCollection:options:
 + fetchAssetsWithOptions:
 + fetchAssetsWithBurstIdentifier:options:
 + fetchAssetsWithALAssetURLs:options:
 其中fetchAssetsInAssetCollection:options:方法可以獲取資源集合中的所有asset對象豫领。每個方法中的 PHFetchOptions參數(shù),是獲取asset對象的一些配置舔琅,我們可以設(shè)置獲取asset的條件,比如獲取哪種資源等恐,如何分類。獲取的時(shí)候,如果該參數(shù)為空课蔬,則使用系統(tǒng)的默認(rèn)值囱稽,當(dāng)我們調(diào)用如上所示方法獲取時(shí),可以直接傳nil

3, 搜索的條件

3.1 PHFetchOptions.h

PHFetchOptions : option的集合二跋,對asset對象進(jìn)行 過濾战惊,排序和管理
屬性:

 [1] predicate 做選擇的約束條件。比如扎即,只獲取圖片吞获,不獲取視頻。指定 PHAssetMediaType為image.

 [2]  sortDescriptors 可指定字段用來對獲取結(jié)果進(jìn)行排序

 [3] includeHiddenAssets 獲取結(jié)果是否包括被隱藏的資源

 [4] includeAllBurstAssets 獲取結(jié)果是否包括連拍資源

 [5] includeAssetSourceTypes 資源的來源
 PHAssetSourceTypeNone
 PHAssetSourceTypeUserLibrary
 PHAssetSourceTypeCloudShared
 PHAssetSourceTypeiTunesSynced

 [6] fetchLimit  搜索結(jié)果的限制 ,0 表示無限制

 [7] wantsIncrementalChangeDetails ,搜索結(jié)果細(xì)節(jié)變化

4, 搜索的結(jié)果 PHFetchResult

PHFetchResult.h
PHFetchResult: 類似數(shù)組,包含assets或者collections有序的一系列集合

特點(diǎn): 同步快速獲取結(jié)果,
即使結(jié)果集很大谚鄙,框架也能保證獲取速度. 因?yàn)樗粫淮涡詫⑺薪Y(jié)果放進(jìn)內(nèi)存各拷,而是按需批量加載
可以用類似 NSArray 的接口來訪問PHFetchResult結(jié)果內(nèi)的集合
提供快速枚舉的方法

  • (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;
    就算滿足請求的照片庫內(nèi)容發(fā)生了改變,獲取方法所返回的 PHFetchResult 對象是不會自動更新闷营。在后面的小節(jié)中烤黍,我們會介紹如何對返回的 PHFetchResult 對象的改變進(jìn)行觀察并處理更新內(nèi)容。
    可以借助 PHObjectChangeDetails 或 PHFetchResultChangeDetails 對象來觀察這些變化

綜合例子如下:

// 獲取相機(jī)膠卷的相冊得到PHAsset對象放到IJSAlbumModel中
-(void)getCameraRollAlbumContentImage:(BOOL)contentImage contentVideo:(BOOL)contentVideo  completion:(void (^)(IJSAlbumModel *model))completion
{
    __block IJSAlbumModel *model;
    if (iOS8Later)
    {
        PHFetchOptions *option = [[PHFetchOptions alloc] init];
        if (!contentVideo) option.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeImage];
        if (!contentImage) option.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld",
                                                    PHAssetMediaTypeVideo];
        if (!self.sortAscendingByModificationDate)
        {
            option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:self.sortAscendingByModificationDate]];
        }
        PHFetchResult<PHAssetCollection *>  *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];

        for (PHAssetCollection *collection in smartAlbums)
        {
            if (![collection isKindOfClass:[PHAssetCollection class]]) continue; // 有可能是PHCollectionList類的的對象粮坞,過濾掉
            if ([self isCameraRollAlbum:collection.localizedTitle])
            {
                PHFetchResult<PHAsset *>  *fetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:option];
                model = [self modelWithResult:fetchResult name:collection.localizedTitle];
                if (completion) completion(model);
                break;
            }
        }
    }
    else
    {
        [self.assetLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
            if ([group numberOfAssets] < 1) return;
            NSString *name = [group valueForProperty:ALAssetsGroupPropertyName];
            if ([self isCameraRollAlbum:name])
            {
                model = [self modelWithResult:group name:name];
                if (completion) completion(model);
                *stop = YES;
            }
        } failureBlock:nil];
    }
}

至此我們已經(jīng)成功的獲取了 asset 對象


接下來我們將我們獲取的 PHAsset對象解析成我們需要 UIImage 對象
需要的類介紹:

5, 解析PHAsset

PHImageManager.h

5.1 PHImageManager

在框架中是個單例對象蚊荣,用[PHImageManager defaultManager]獲取,它提供了加載圖片和視頻的方法,解析 PHAsset 資源
方法介紹:

// 獲取自定義大小的圖片
- (PHImageRequestID)requestImageForAsset:(PHAsset *)asset targetSize:(CGSize)targetSize contentMode:(PHImageContentMode)contentMode options:(nullable PHImageRequestOptions *)options resultHandler:(void (^)(UIImage *__nullable result, NSDictionary *__nullable info))resultHandler;
官方注釋翻譯:
 如果獲取的資源的寬高比不符合, contentMode 決定現(xiàn)實(shí)的大小
 PHImageContentModeAspectFit:  等比例適應(yīng)
 PHImageContentModeAspectFill:  等比例縮放適應(yīng)
 PHImageContentModeDefault = PHImageContentModeAspectFit  默認(rèn)值
 [PHImageRequestOptions isSynchronous] returns NO (or options is nil), resultHandler 可能會請求多次
 deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic
 默認(rèn)情況下,這些API是異步執(zhí)行莫杈,但是我們可以通過options參數(shù)中的synchronous屬性互例,設(shè)置為同步執(zhí)行,這些方法會阻塞當(dāng)前調(diào)用線程直到下載完成或者發(fā)生錯誤
 請求取消將不再返回 resultHandler

方法參數(shù)解讀:
 asset:   需要解析的資源
 targetSize: 需要獲取的圖像的尺寸筝闹,如果輸入的尺寸大于資源原圖的尺寸媳叨,則只返回原圖。需要注意在 PHImageManager 中关顷,所有的尺寸都是用 Pixel 作為單位(Note that all sizes are in pixels)糊秆,因此這里想要獲得正確大小的圖像,需要把輸入的尺寸轉(zhuǎn)換為 Pixel议双。如果需要返回原圖尺寸痘番,可以傳入 PhotoKit 中預(yù)先定義好的常量?PHImageManagerMaximumSize,表示返回可選范圍內(nèi)的最大的尺寸平痰,即原圖尺寸
 contentMode: 圖像的剪裁方式,控制照片應(yīng)該以按比例縮放還是按比例填充的方式放到最終展示的容器內(nèi)汞舱。注意如果 targetSize 傳入PHImageManagerMaximumSize,則 contentMode 無論傳入什么值都會被視為 PHImageContentModeDefault
 options: PHImageRequestOptions 的實(shí)例宗雇,可以控制的內(nèi)容相當(dāng)豐富昂芜,包括圖像的質(zhì)量、版本赔蒲,也會有參數(shù)控制圖像的剪裁
 resultHandler: 請求結(jié)束后被調(diào)用的 block泌神,返回一個包含資源對于圖像的 UIImage 和包含圖像信息的一個 NSDictionary良漱,在整個請求的周期中,這個 block 可能會被多次調(diào)用

// 獲取原圖數(shù)據(jù)
請求大圖 ,回調(diào)只執(zhí)行一次,deliveryMode直接被忽略,設(shè)置了PHImageRequestOptionsVersionCurrent 并且資源被調(diào)整過,則返回最大的圖
- (PHImageRequestID)requestImageDataForAsset:(PHAsset *)asset options:(nullable PHImageRequestOptions *)options resultHandler:(void(^)(NSData *__nullable imageData, NSString *__nullable dataUTI, UIImageOrientation orientation, NSDictionary *__nullable info))resultHandler;
// 取消正在加載的數(shù)據(jù)線
- (void)cancelImageRequest:(PHImageRequestID)requestID;

5.2 獲取圖片資源的控制條件類 PHImageRequestOptions

PHImageRequestOptions中包含了一系列控制請求圖像的屬性
如果resizeMode所控制的剪裁結(jié)果有所沖突欢际,PhotoKit 會以 resizeMode 的結(jié)果為準(zhǔn)
屬性詳解:

1,  PHImageRequestOptionsVersion version:

 這個屬性是指獲取的圖像是否需要包含系統(tǒng)相冊“編輯”功能處理過的信息(如濾鏡母市,旋轉(zhuǎn)等)
 圖片編輯extension,可以根據(jù)次枚舉獲取原圖或者是經(jīng)編輯過的圖片
 PHImageRequestOptionsVersionCurrent = 0, //當(dāng)前的(編輯過?經(jīng)過編輯的圖:原圖)
 PHImageRequestOptionsVersionUnadjusted, //經(jīng)過編輯的圖
 PHImageRequestOptionsVersionOriginal       //原始圖片

  2, PHImageRequestOptionsDeliveryMode deliveryMode:
 則用于控制請求的圖片質(zhì)量
 PHImageRequestOptionsDeliveryModeOpportunistic:在速度與質(zhì)量中均衡 根據(jù)我options.synchronous判斷返回結(jié)果是一個或多個
 PHImageRequestOptionsDeliveryModeHighQualityFormat 制定的同步返回一個結(jié)果损趋,返回的圖片質(zhì)量是比我們設(shè)定的size會好一點(diǎn)(實(shí)際上與PHImageRequestOptions的resizeMode枚舉相關(guān)) 高質(zhì)量圖
 PHImageRequestOptionsDeliveryModeFastFormat 僅返回一次窒篱,效率較高之余獲得的圖質(zhì)量不太好,速度最快

  3, PHImageRequestOptionsResizeMode resizeMode:  PHImageRequestOptionsResizeModeNone (or no resize)無效 屬性控制圖像的剪裁

 4 CGRect normalizedCropRect: 用于對原始尺寸的圖像進(jìn)行裁剪,基于比例坐標(biāo)舶沿。只在 resizeMode 為 Exact 時(shí)有效
 5 BOOL networkAccessAllowed; 是否允許從 icloud請求資源 另一個和 iCloud 相關(guān)的屬性是 progressHandler。你可以將它設(shè)為一個PHAssetImageProgressHandler 的 block配并,當(dāng)從 iCloud 下載照片時(shí)括荡,它就會被圖像管理器自動調(diào)用
 6 BOOL synchronous 是否為同步操作,默認(rèn)為NO溉旋,如果設(shè)置為YES則畸冲,相關(guān)模式下只會返回一張圖片
  PHAssetImageProgressHandler progressHandler 當(dāng)圖像需要從 iCloud 下載時(shí),這個 block 會被自動調(diào)用观腊,block 中會返回圖像下載的進(jìn)度邑闲,圖像的信息,出錯信息梧油。開發(fā)者可以利用這些信息反饋給用戶當(dāng)前圖像的下載進(jìn)度以及狀況苫耸,但需要注意?progressHandler 不在主線程上執(zhí)行,因此在其中需要操作 UI儡陨,則需要手工放到主線程執(zhí)行
 上面有提到褪子,requestImageForAsset 中的參數(shù)?resultHandler 可能會被多次調(diào)用,這種情況就是圖像需要從 iCloud 中下載的情況骗村。在?requestImageForAsset 返回的內(nèi)容中嫌褪,一開始的那一次請求中會返回一個小尺寸的圖像版本,當(dāng)高清圖像還在下載時(shí)胚股,開發(fā)者可以首先給用戶展示這個低清的圖像版本笼痛,然后 block 在多次調(diào)用后,最終會返回高清的原圖琅拌。至于當(dāng)前返回的圖像是哪個版本的圖像缨伊,可以通過 block 返回的 NSDictionary info 中獲知,PHImageResultIsDegradedKey 表示當(dāng)前返回的 UIImage 是低清圖财忽。如果需要判斷是否已經(jīng)獲得高清圖倘核,可以這樣判斷:

 BOOL downloadFinined = (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey]);

 requestImageForAsset 發(fā)出對圖像的請求時(shí),如果在同一個 PHImageManager 中同時(shí)對同一個資源發(fā)出圖像請求即彪,請求的進(jìn)度是可以共享的紧唱,因此我們可以利用這個特性活尊,把 PHImageManager 以單例的形式使用,這樣在切換界面時(shí)也不用擔(dān)心無法傳遞圖像的下載進(jìn)度漏益。例如蛹锰,在圖像的列表頁面觸發(fā)了下載圖像,當(dāng)我們離開列表頁面進(jìn)入預(yù)覽大圖界面時(shí)绰疤,并不用擔(dān)心會重新圖像會重新下載铜犬,只要沒有手工取消圖像下載,進(jìn)入預(yù)覽大圖界面下載圖像會自動繼續(xù)從上次的進(jìn)度下載圖像

5.3 livePhoto篩選類 PHLivePhotoRequestOptions
 PHImageRequestOptionsVersion version;
  PHImageRequestOptionsDeliveryMode deliveryMode;
  BOOL networkAccessAllowed;
  PHAssetImageProgressHandler progressHandler;// 網(wǎng)絡(luò)加載的進(jìn)度

5.4 video篩選類 PHVideoRequestOptions
BOOL networkAccessAllowed;
PHVideoRequestOptionsVersion version;
 PHVideoRequestOptionsDeliveryMode deliveryMode;
 PHAssetVideoProgressHandler progressHandler;  // 網(wǎng)絡(luò)進(jìn)度

 // 獲取視頻
 - (PHImageRequestID)requestPlayerItemForVideo:(PHAsset *)asset options:(nullable PHVideoRequestOptions *)options resultHandler:(void (^)(AVPlayerItem *__nullable playerItem, NSDictionary *__nullable info))resultHandler;
 // 導(dǎo)出視頻方法
 - (PHImageRequestID)requestAVAssetForVideo:(PHAsset *)asset options:(nullable PHVideoRequestOptions *)options resultHandler:(void (^)(AVAsset *__nullable asset, AVAudioMix *__nullable audioMix, NSDictionary *__nullable info))resultHandler;

5.5 PHPhotoLibrary

PHPhotoLibrary:
系統(tǒng)中PHPhotoLibrary單例對象 是用來維護(hù)用戶照片庫轻庆。當(dāng)我們需要編輯資源對象元數(shù)據(jù)癣猾、資源內(nèi)容、或者插入新的資源對象等余爆,都可以借助通過PHPhotoLibrary單例對象執(zhí)行block纷宇,block中創(chuàng)建我們指定的請求對象(比如PHAssetChangeRequest,PHAssetCollectionChangeRequest, PHCollectionListChangeRequest的對象)。photoLibraryDidChange(changeInfo: PHChange!)中進(jìn)行
授權(quán)狀態(tài)

 {
 PHAuthorizationStatusNotDetermined = 0, // 未選擇
 PHAuthorizationStatusRestricted,        // 用戶受到某些限制蛾方,不能自己決定像捶,比如:家長控制
 PHAuthorizationStatusDenied,            // 用戶明確拒絕
 PHAuthorizationStatusAuthorized         // 已經(jīng)授權(quán)
 }

 // 協(xié)議 :
 PHPhotoLibraryChangeObserver:
 PHPhotoLibraryChangeObserver 協(xié)議能讓我們知道照片相冊庫中的改變。Photos會發(fā)送系統(tǒng)圖片改變的消息桩砰,我們可以遵守PHPhotoLibraryChangeObserver協(xié)議拓春,并通過 PHPhotoLibrary的registerChangeObserver方法將對象注冊為觀察者,時(shí)時(shí)接收照片改變的消息亚隅。
 // 串行隊(duì)列 相冊數(shù)據(jù)改變 知道照片相冊庫中的改變
 - (void)photoLibraryDidChange:(PHChange *)changeInstance;

 // 單利初始化
 + (PHPhotoLibrary *)sharedPhotoLibrary;
 //判斷授權(quán)
 + (PHAuthorizationStatus)authorizationStatus;
 請求授權(quán)
 + (void)requestAuthorization:(void(^)(PHAuthorizationStatus status))handler;

 //  執(zhí)行同步和異步數(shù)據(jù)
 - (void)performChanges:(dispatch_block_t)changeBlock completionHandler:(nullable void(^)(BOOL success, NSError *__nullable error))completionHandler;
 - (BOOL)performChangesAndWait:(dispatch_block_t)changeBlock error:(NSError *__autoreleasing *)error;

 // 將對象注冊為觀察者硼莽,時(shí)時(shí)接收照片改變的消息。
 - (void)registerChangeObserver:(id<PHPhotoLibraryChangeObserver>)observer;
 - (void)unregisterChangeObserver:(id<PHPhotoLibraryChangeObserver>)observer;

綜合例子

- (PHImageRequestID)getPhotoWithAsset:(id)asset photoWidth:(CGFloat)photoWidth completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed
{
    if ([asset isKindOfClass:[PHAsset class]]) {
        CGSize imageSize;
        if (photoWidth < JSScreenWidth && photoWidth < _photoPreviewMaxWidth) {
            imageSize = assetGridThumbnailSize;
        } else {
            PHAsset *phAsset = (PHAsset *)asset;
            CGFloat aspectRatio = phAsset.pixelWidth / (CGFloat)phAsset.pixelHeight;
            CGFloat pixelWidth = photoWidth * JSScreenScale * 1.5;
            // 超寬圖片
            if (aspectRatio > 1) {
                pixelWidth = pixelWidth * aspectRatio;
            }
            // 超高圖片
            if (aspectRatio < 0.2) {
                pixelWidth = pixelWidth * 0.5;
            }
            CGFloat pixelHeight = pixelWidth / aspectRatio;
            imageSize = CGSizeMake(pixelWidth, pixelHeight);
        }

        __block UIImage *image;
        PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
        option.resizeMode = PHImageRequestOptionsResizeModeFast;
        int32_t imageRequestID = [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:imageSize contentMode:PHImageContentModeAspectFill options:option resultHandler:^(UIImage *result, NSDictionary *info) {
            if (result) {
                image = result;
            }
            BOOL downloadFinined = (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey]);
            if (downloadFinined && result) {
                result = [self fixOrientation:result];
                if (completion) completion(result,info,[[info objectForKey:PHImageResultIsDegradedKey] boolValue]);
            }
            // Download image from iCloud / 從iCloud下載圖片
            if ([info objectForKey:PHImageResultIsInCloudKey] && !result && networkAccessAllowed) {
                PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
                options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        if (progressHandler) {
                            progressHandler(progress, error, stop, info);
                        }
                    });
                };
                options.networkAccessAllowed = YES;
                options.resizeMode = PHImageRequestOptionsResizeModeFast;
                [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
                    UIImage *resultImage = [UIImage imageWithData:imageData scale:0.1];
                    resultImage = [self scaleImage:resultImage toSize:imageSize];
                    if (!resultImage) {
                        resultImage = image;
                    }
                    resultImage = [self fixOrientation:resultImage];
                    if (completion) completion(resultImage,info,NO);
                }];
            }
        }];
        return imageRequestID;
    } else if ([asset isKindOfClass:[ALAsset class]]) {
        ALAsset *alAsset = (ALAsset *)asset;
        dispatch_async(dispatch_get_global_queue(0,0), ^{
            CGImageRef thumbnailImageRef = alAsset.thumbnail;
            UIImage *thumbnailImage = [UIImage imageWithCGImage:thumbnailImageRef scale:2.0 orientation:UIImageOrientationUp];
            dispatch_async(dispatch_get_main_queue(), ^{
                if (completion) completion(thumbnailImage,nil,YES);

                if (photoWidth == JSScreenWidth || photoWidth == _photoPreviewMaxWidth) {
                    dispatch_async(dispatch_get_global_queue(0,0), ^{
                        ALAssetRepresentation *assetRep = [alAsset defaultRepresentation];
                        CGImageRef fullScrennImageRef = [assetRep fullScreenImage];
                        UIImage *fullScrennImage = [UIImage imageWithCGImage:fullScrennImageRef scale:2.0 orientation:UIImageOrientationUp];

                        dispatch_async(dispatch_get_main_queue(), ^{
                            if (completion) completion(fullScrennImage,nil,NO);
                        });
                    });
                }
            });
        });
    }
    return 0;
}

至此關(guān)于photo獲取資源的方法全部結(jié)束

鏈接:http://www.reibang.com/p/119bd419c172

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末枢步,一起剝皮案震驚了整個濱河市沉删,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌醉途,老刑警劉巖矾瑰,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異隘擎,居然都是意外死亡殴穴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門货葬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來采幌,“玉大人,你說我怎么就攤上這事震桶⌒莅” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵蹲姐,是天一觀的道長磨取。 經(jīng)常有香客問我人柿,道長,這世上最難降的妖魔是什么忙厌? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任凫岖,我火速辦了婚禮,結(jié)果婚禮上逢净,老公的妹妹穿的比我還像新娘哥放。我一直安慰自己,他們只是感情好爹土,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布甥雕。 她就那樣靜靜地躺著,像睡著了一般胀茵。 火紅的嫁衣襯著肌膚如雪犀农。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天宰掉,我揣著相機(jī)與錄音,去河邊找鬼赁濒。 笑死轨奄,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拒炎。 我是一名探鬼主播挪拟,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼击你!你這毒婦竟也來了玉组?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤丁侄,失蹤者是張志新(化名)和其女友劉穎惯雳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸿摇,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡石景,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拙吉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片潮孽。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖筷黔,靈堂內(nèi)的尸體忽然破棺而出往史,到底是詐尸還是另有隱情,我是刑警寧澤佛舱,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布椎例,位于F島的核電站挨决,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏粟矿。R本人自食惡果不足惜凰棉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望陌粹。 院中可真熱鬧撒犀,春花似錦、人聲如沸掏秩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒙幻。三九已至映凳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間邮破,已是汗流浹背诈豌。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抒和,地道東北人矫渔。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像摧莽,于是被迫代替她去往敵國和親庙洼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

  • 見識:1.讀書的錢不能省 北大的陳平實(shí)說:如果你半夜醒來镊辕,發(fā)現(xiàn)自己已經(jīng)好長時(shí)間沒讀書油够,而且沒有任何負(fù)罪感的時(shí)候,你...
    張同學(xué)V閱讀 328評論 0 0
  • 本自富足 外面沒有別人只有你自己—《親密關(guān)系》征懈。 上次向前一步讀書會石咬,紹芬邀請我參加下一次12月8號的活動作為分享...
    妮妮諾拉閱讀 381評論 0 1
  • 我一直是鼓勵父母提前給孩子進(jìn)行學(xué)習(xí)的能力、習(xí)慣和意識的培養(yǎng)的卖哎。只要孩子學(xué)有余力碌补,都應(yīng)該提倡超前學(xué)習(xí)。但是最近一系列...
    jiajiasoso閱讀 776評論 0 3
  • 2015年年初由于團(tuán)隊(duì)發(fā)展的需要,我從技術(shù)崗轉(zhuǎn)到運(yùn)營照藻,到現(xiàn)在差不多一年了袜啃。總得來說上半年苦苦摸索幸缕,下半年漸入佳境群发。...
    ZMO新媒體學(xué)院閱讀 1,785評論 0 3