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)圖:
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é)束