PhotoKit制作相冊(cè)或選擇器(一):初識(shí)Photos

前言

不知讀者們?cè)谄饺绽锸褂昧奶旃ぞ邥r(shí)礁凡,有沒有發(fā)表情的習(xí)慣。是不是常常在與朋友們聊天時(shí)慧妄,一言不合就掀起一場(chǎng)斗圖大會(huì)呢顷牌。小編作為一個(gè)喜歡搞事情的小碼農(nóng),上班唯一能放松的事情就是和同事在群里吹牛逼斗斗圖了(不搞點(diǎn)事情代碼怎么吐的動(dòng)呢)腰涧。
找不到圖源韧掩,微信表情又有上限等,種種問題讓我施展不出真正的斗圖實(shí)力(中毒太深)窖铡。非得搞點(diǎn)事情的我計(jì)劃開發(fā)一款制作管理GIF表情的相冊(cè)疗锐,名字叫斗逗圖(目前五菱宏光版正在審核中......)
這波廣告小編打得自己都臉紅了。费彼。滑臊。那來切入正題吧,在開發(fā)過程中箍铲,我需要通過圖片選擇器選擇多張圖片雇卷,可是強(qiáng)大的UIImagePickerController卻沒有多選功能,這讓我很憂桑,看了看Github关划,已經(jīng)有比較好的輪子小染,但樣式固定死了,太花哨了贮折,畢竟咱是五菱宏光裤翩,漂移之王,花哨的輪子漂不起來调榄,還是自己用Photos造一個(gè)吧踊赠。

關(guān)于Photos

資源

PHObject:資源基類,PHAsset每庆、PHCollecton等都繼承它筐带,它包含了一個(gè)屬性localIdentifier,它是唯一的缤灵,所以我們可以通過此屬性來判斷資源對(duì)象是否是同一個(gè)
PHAsset:代表一個(gè)在相冊(cè)中的圖片或視頻伦籍,它本身并不儲(chǔ)存圖片或視頻資源,它存放的是metaData,需要通過PHImageManager來請(qǐng)求才能獲取圖片或視頻資源腮出。
PHCollection:照片庫中單獨(dú)輕量不可變的集合對(duì)象
PHAssetCollectionPHCollection的子類鸽斟,可以通過它獲取系統(tǒng)自帶的相冊(cè)信息
PHCollectionList:既是PHCollection的子類,也是PHCollection的集合
PHFetchResult:很像NSFetchRequest吧利诺,它也有predicatesortDescriptors;使用起來剩燥,它類似NSArray慢逾,可以通過遍歷獲取儲(chǔ)存的各個(gè)元素;還能通過觀察者模式來檢測(cè)相冊(cè)內(nèi)容是否變化灭红。

獲取資源

PHAssetCollection類方法獲取相冊(cè)的資源

#pragma mark - Fetching asset collections

+ (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsWithLocalIdentifiers:(NSArray<NSString *> *)identifiers options:(nullable PHFetchOptions *)options;
+ (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsWithType:(PHAssetCollectionType)type subtype:(PHAssetCollectionSubtype)subtype options:(nullable PHFetchOptions *)options;

// Smart Albums are not supported, only Albums and Moments
+ (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsContainingAsset:(PHAsset *)asset withType:(PHAssetCollectionType)type options:(nullable PHFetchOptions *)options;

// assetGroupURLs are URLs retrieved from ALAssetGroup's ALAssetsGroupPropertyURL
+ (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsWithALAssetGroupURLs:(NSArray<NSURL *> *)assetGroupURLs options:(nullable PHFetchOptions *)options;

#pragma mark - Fetching moment asset collections

+ (PHFetchResult<PHAssetCollection *> *)fetchMomentsInMomentList:(PHCollectionList *)momentList options:(nullable PHFetchOptions *)options;
+ (PHFetchResult<PHAssetCollection *> *)fetchMomentsWithOptions:(nullable PHFetchOptions *)options;

PHAsset類方法獲取分類過后的資源

#pragma mark - Fetching assets

+ (PHFetchResult<PHAsset *> *)fetchAssetsInAssetCollection:(PHAssetCollection *)assetCollection options:(nullable PHFetchOptions *)options;
+ (PHFetchResult<PHAsset *> *)fetchAssetsWithLocalIdentifiers:(NSArray<NSString *> *)identifiers options:(nullable PHFetchOptions *)options;
+ (nullable PHFetchResult<PHAsset *> *)fetchKeyAssetsInAssetCollection:(PHAssetCollection *)assetCollection options:(nullable PHFetchOptions *)options;
+ (PHFetchResult<PHAsset *> *)fetchAssetsWithBurstIdentifier:(NSString *)burstIdentifier options:(nullable PHFetchOptions *)options;

// Fetches PHAssetSourceTypeUserLibrary assets by default (use includeAssetSourceTypes option to override)
+ (PHFetchResult<PHAsset *> *)fetchAssetsWithOptions:(nullable PHFetchOptions *)options;
+ (PHFetchResult<PHAsset *> *)fetchAssetsWithMediaType:(PHAssetMediaType)mediaType options:(nullable PHFetchOptions *)options;

// assetURLs are URLs retrieved from ALAsset's ALAssetPropertyAssetURL
+ (PHFetchResult<PHAsset *> *)fetchAssetsWithALAssetURLs:(NSArray<NSURL *> *)assetURLs options:(nullable PHFetchOptions *)options;

返回的類型都是PHFetchResult侣滩,里面存放的并不是一個(gè)個(gè)的圖片原始資源,而只是一個(gè)個(gè)包含元數(shù)據(jù)的PHAsset变擒。那我們?cè)撊绾潍@取圖片的原始資源呢君珠?這就該用到PHImageManager類。

請(qǐng)求資源

PHImageManager
此類提供了請(qǐng)求加載圖片或視頻數(shù)據(jù)的方法娇斑,既可以獲取原始大小的圖片策添,也能獲取縮略圖,同時(shí)也可以取回用作播放的AVFoundation相關(guān)對(duì)象或者操作視頻資源毫缆。
當(dāng)同時(shí)加載多個(gè)資源很快顯示出來時(shí)唯竹, 可以使用PHCachingImageManager
類預(yù)加載圖片至緩存,這個(gè)會(huì)在之后的文章中寫到苦丁。

以下方法都是實(shí)例方法浸颓,調(diào)用時(shí)需要使用defaultManager

請(qǐng)求圖片

方法列表:
#pragma mark - Image
- (PHImageRequestID)requestImageForAsset:(PHAsset *)asset targetSize:(CGSize)targetSize contentMode:(PHImageContentMode)contentMode options:(nullable PHImageRequestOptions *)options resultHandler:(void (^)(UIImage *__nullable result, NSDictionary *__nullable info))resultHandler;


// resultHandler for asynchronous requests, always called on main thread
- (PHImageRequestID)requestImageDataForAsset:(PHAsset *)asset options:(nullable PHImageRequestOptions *)options resultHandler:(void(^)(NSData *__nullable imageData, NSString *__nullable dataUTI, UIImageOrientation orientation, NSDictionary *__nullable info))resultHandler;
//請(qǐng)求方法都返回了PHImageRequestID,可以通過此ID來取消請(qǐng)求
- (void)cancelImageRequest:(PHImageRequestID)requestID;
targetSize

目標(biāo)尺寸

contentMode

如果資源的比例與所給的目標(biāo)大小不匹配的話,contentMode決定了圖片如何改變
(詳細(xì)可看PHImageRequestOptionsDeliveryModePHImageRequestOptionsResizeMode)

  •  **PHImageContentModeAspectFit**:使圖片根據(jù)目標(biāo)大小完整顯示 
    
  •  **PHImageContentModeAspectFill**:使圖片根據(jù)目標(biāo)大小裁剪顯示
    
  •  **PHImageContentModeDefault**: 當(dāng)尺寸設(shè)置為```PHImageManagerMaximumSize```時(shí)使用```PHImageContentModeDefault```产上,得到的結(jié)果沒有經(jīng)過縮放和裁剪
    
options
  • version
    當(dāng)version等于PHImageRequestOptionsVersionCurrent請(qǐng)求返回資源是已經(jīng)調(diào)整過后最大的圖片數(shù)據(jù)
  • synchronous
    請(qǐng)求是否同步執(zhí)行棵磷,值為NO時(shí),會(huì)根據(jù)deliveryMode這個(gè)屬性晋涣,等待方法的回調(diào)仪媒;當(dāng)為YES時(shí),deliveryMode的值會(huì)被忽略姻僧,resultHandler這個(gè)回調(diào)也只會(huì)執(zhí)行一次
  • resizeMode:圖像變化方式规丽。
Fast:盡快地提供接近要求的尺寸;
Exact:精準(zhǔn)提供要求的尺寸撇贺。
deliveryMode:圖像質(zhì)量赌莺。
Opportunistic:臨時(shí)圖像;
HighQualityFormat:高質(zhì)量圖像松嘶;
FastFormat艘狭,以最快速度提供好的質(zhì)量。 這個(gè)屬性只有在 synchronous 為 true 時(shí)有效翠订。
  • normalizedCropRect
    用于對(duì)原始尺寸的圖像進(jìn)行裁剪巢音,基于比例坐標(biāo)。只在 resizeModeExact 時(shí)有效尽超。
resultHandler

此代碼塊是異步執(zhí)行的官撼,如果deliveryMode等于PHImageRequestOptionsDeliveryModeOpportunistic時(shí),先會(huì)同步返回一個(gè)臨時(shí)的低質(zhì)量資源似谁,之后當(dāng)請(qǐng)求到所需的圖片資源時(shí)傲绣,會(huì)異步返回;options 參數(shù)的作用就是來定制這些行為

請(qǐng)求LivePhoto

請(qǐng)求LivePhoto資源巩踏。如果 PHLivePhotoRequestOptions
deliveryMode
PHImageRequestOptionsDeliveryModeOpportunistic或者optionsnil時(shí)秃诵,resultHandler回調(diào)不止一次,并且有可能會(huì)在同步方法返回前先返回
resultHandler回調(diào)代碼塊的Info字典PHImageResultIsDegradedKey對(duì)應(yīng)的值代表是否低質(zhì)量的LivePhoto已經(jīng)提供

#pragma mark - Live Photo
//Live Photo
- (PHImageRequestID)requestLivePhotoForAsset:(PHAsset *)asset targetSize:(CGSize)targetSize contentMode:(PHImageContentMode)contentMode options:(nullable PHLivePhotoRequestOptions *)options resultHandler:(void (^)(PHLivePhoto *__nullable livePhoto, NSDictionary *__nullable info))resultHandler NS_AVAILABLE_IOS(9_1);

請(qǐng)求視頻

#pragma mark - Video

//可播放視頻音頻資源
- (PHImageRequestID)requestPlayerItemForVideo:(PHAsset *)asset options:(nullable PHVideoRequestOptions *)options resultHandler:(void (^)(AVPlayerItem *__nullable playerItem, NSDictionary *__nullable info))resultHandler;

// 導(dǎo)出會(huì)話
- (PHImageRequestID)requestExportSessionForVideo:(PHAsset *)asset options:(nullable PHVideoRequestOptions *)options exportPreset:(NSString *)exportPreset resultHandler:(void (^)(AVAssetExportSession *__nullable exportSession, NSDictionary *__nullable info))resultHandler;

// 其他
- (PHImageRequestID)requestAVAssetForVideo:(PHAsset *)asset options:(nullable PHVideoRequestOptions *)options resultHandler:(void (^)(AVAsset *__nullable asset, AVAudioMix *__nullable audioMix, NSDictionary *__nullable info))resultHandler;

觀察相冊(cè)變更

相冊(cè)里多了一張照片塞琼,如何及時(shí)的顯示出來呢菠净?
此時(shí)PHPhotoLibraryChangeObserver的作用就體現(xiàn)出來了
顧名思義,它就類似一個(gè)觀察者彪杉,監(jiān)測(cè)變化毅往,反應(yīng)變化。
使用步驟:

  1. 添加此協(xié)議<PHPhotoLibraryChangeObserver>
- (void)viewWillAppear:(BOOL)animated {
    //注冊(cè)觀察相冊(cè)變化的觀察者
    [[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self];
}
- (void)dealloc {
    //銷毀觀察相冊(cè)變化的觀察者
    [[PHPhotoLibrary sharedPhotoLibrary] unregisterChangeObserver:self];
}

2.實(shí)現(xiàn)協(xié)議

- (void)photoLibraryDidChange:(PHChange *)changeInstance;

PHChangechangeDetailsForFetchResult:方法檢測(cè)照片集合內(nèi)是否產(chǎn)生變化派近,入?yún)楸粰z測(cè)的照片集合

- (nullable PHFetchResultChangeDetails *)changeDetailsForFetchResult:(PHFetchResult *)object;

結(jié)束語

以上是關(guān)于Photos框架的簡(jiǎn)單介紹煞抬,一些基本的用法,足夠開發(fā)一款簡(jiǎn)單的相冊(cè)或者選擇器啦构哺!
這回買好零件革答,下一篇就開始造我們五菱宏光專屬輪子了战坤。
敬請(qǐng)期待~

小編對(duì)文檔的理解可能會(huì)有些出入,有錯(cuò)誤希望讀者能積極指出残拐,我會(huì)及時(shí)更正途茫。
如果喜歡,請(qǐng)持續(xù)關(guān)注溪食,順便點(diǎn)個(gè)喜歡噢??????

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末囊卜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子错沃,更是在濱河造成了極大的恐慌栅组,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枢析,死亡現(xiàn)場(chǎng)離奇詭異玉掸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)醒叁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門司浪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人把沼,你說我怎么就攤上這事啊易。” “怎么了饮睬?”我有些...
    開封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵租谈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我捆愁,道長(zhǎng)垦垂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任牙瓢,我火速辦了婚禮,結(jié)果婚禮上间校,老公的妹妹穿的比我還像新娘矾克。我一直安慰自己,他們只是感情好憔足,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開白布胁附。 她就那樣靜靜地躺著,像睡著了一般滓彰。 火紅的嫁衣襯著肌膚如雪控妻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天揭绑,我揣著相機(jī)與錄音弓候,去河邊找鬼郎哭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛菇存,可吹牛的內(nèi)容都是我干的夸研。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼依鸥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼亥至!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贱迟,我...
    開封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤姐扮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后衣吠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茶敏,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年蒸播,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了睡榆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡袍榆,死狀恐怖胀屿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情包雀,我是刑警寧澤宿崭,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站才写,受9級(jí)特大地震影響葡兑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赞草,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一讹堤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧厨疙,春花似錦洲守、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至撒蟀,卻和暖如春叙谨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工刽辙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蓖议,地道東北人是牢。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓慎恒,卻偏偏與公主長(zhǎng)得像稳衬,于是被迫代替她去往敵國(guó)和親初橘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子耐朴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

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