iOS Photos 框架使用

Photos

Photos 框架是iOS 8之后用于替代AssetsLibrary的一個現(xiàn)代化框架揽惹,幾年以來,相機應(yīng)用與照片應(yīng)用發(fā)生了顯著的變化四康,增加了許多新特性搪搏,Photos可以獲取相冊中的所有圖片和視頻資源,包括iCloud Photo library 和 Live Photos闪金,并且能夠異步獲取并緩存縮略圖和原圖疯溺。

獲取資源

相冊中有兩種資源可供獲取,分別是PHAssetPHCollection哎垦,PHAsset代表一個相冊中的文件,這個文件可以是視頻囱嫩、音頻或圖片,我們可以通過PHAsset來獲取這個文件的所有信息撼泛,包括定位挠说、創(chuàng)建時間、名稱等等愿题。而PHCollection則是一個集合损俭,PHCollection有兩個子類分別是PHAssetCollectionPHCollectionList,其中PHAssetCollection代表一個相冊潘酗,也就是PHAsset的集合杆兵,如自拍相冊、截屏相冊仔夺、智能相冊等琐脏。PHCollectionList代表一個自身的集合,也就是PHCollection的集合缸兔,通常用來獲取相冊列表

對應(yīng)關(guān)系

獲取請求

所有的獲取操作都是由PHAsset和PHCollection的類方法實現(xiàn)的日裙,方法如下:

//獲取一個相冊中的所有文件
open class func fetchAssets(in assetCollection: PHAssetCollection, options: PHFetchOptions?) -> PHFetchResult<PHAsset>
//通過PHAsset的LocalIdentifier獲取PHAsset
open class func fetchAssets(withLocalIdentifiers identifiers: [String], options: PHFetchOptions?) -> PHFetchResult<PHAsset> // includes hidden assets by default
open class func fetchKeyAssets(in assetCollection: PHAssetCollection, options: PHFetchOptions?) -> PHFetchResult<PHAsset>?
//通過PHAsset的burstIdentifier獲取PHAsset,burstIdentifier是連拍模式才會有的id,通過該id可以獲取連拍模式的所有照片
open class func fetchAssets(withBurstIdentifier burstIdentifier: String, options: PHFetchOptions?) -> PHFetchResult<PHAsset>

// Fetches PHAssetSourceTypeUserLibrary assets by default (use includeAssetSourceTypes option to override)
open class func fetchAssets(with options: PHFetchOptions?) -> PHFetchResult<PHAsset>
//獲取對應(yīng)類型的PHAsset
open class func fetchAssets(with mediaType: PHAssetMediaType, options: PHFetchOptions?) -> PHFetchResult<PHAsset>

// assetURLs are URLs retrieved from ALAsset's ALAssetPropertyAssetURL
@available(iOS, introduced: 8.0, deprecated: 11.0, message: "Will be removed in a future release")
open class func fetchAssets(withALAssetURLs assetURLs: [URL], options: PHFetchOptions?) -> PHFetchResult<PHAsset>

其中fetchAssetsInAssetCollection:options:方法可以獲取資源集合中的所有asset對象惰蜜。每個方法中的 PHFetchOptions參數(shù)昂拂,是獲取asset對象的一些配置,我們可以設(shè)置獲取asset的條件,比如獲取哪種資源抛猖,如何分類格侯。獲取的時候,如果該參數(shù)為空财著,則使用系統(tǒng)的默認值联四,當(dāng)我們調(diào)用如上所示方法獲取時,可以直接傳nil撑教。

// Fetch asset collections of a single type matching the provided local identifiers (type is inferred from the local identifiers)
//通過LocalIdentifier和option獲取相冊
open class func fetchAssetCollections(withLocalIdentifiers identifiers: [String], options: PHFetchOptions?) -> PHFetchResult<PHAssetCollection>


// Fetch asset collections of a single type and subtype provided (use PHAssetCollectionSubtypeAny to match all subtypes)
//通過相冊類型獲取相冊
open class func fetchAssetCollections(with type: PHAssetCollectionType, subtype: PHAssetCollectionSubtype, options: PHFetchOptions?) -> PHFetchResult<PHAssetCollection>

// Smart Albums are not supported, only Albums and Moments
//獲取包含對應(yīng)PHAsset的相冊朝墩,Smart Albums(系統(tǒng)分配智能的相冊,PHAssetCollectionType枚舉中選擇)不支持
open class func fetchAssetCollectionsContaining(_ asset: PHAsset, with type: PHAssetCollectionType, options: PHFetchOptions?) -> PHFetchResult<PHAssetCollection>


// assetGroupURLs are URLs retrieved from ALAssetGroup's ALAssetsGroupPropertyURL
//通過URL獲取相冊驮履,assetGroupURLs是通過AssetsLibrary獲取的URLs
open class func fetchAssetCollections(withALAssetGroupURLs assetGroupURLs: [URL], options: PHFetchOptions?) -> PHFetchResult<PHAssetCollection>

//獲取一個集合中PHAssetCollectionType 為moment的相冊
open class func fetchMoments(inMomentList momentList: PHCollectionList, options: PHFetchOptions?) -> PHFetchResult<PHAssetCollection>
//獲取所有PHAssetCollectionType為moment的相冊
open class func fetchMoments(with options: PHFetchOptions?) -> PHFetchResult<PHAssetCollection>
PHCollectionList
// A PHAssetCollectionTypeMoment will be contained by a PHCollectionListSubtypeMomentListCluster and a PHCollectionListSubtypeMomentListYear
// Non-moment PHAssetCollections will only be contained by a single collection list
open class func fetchCollectionListsContaining(_ collection: PHCollection, options: PHFetchOptions?) -> PHFetchResult<PHCollectionList>

// Fetch collection lists of a single type matching the provided local identifiers (type is inferred from the local identifiers)
open class func fetchCollectionLists(withLocalIdentifiers identifiers: [String], options: PHFetchOptions?) -> PHFetchResult<PHCollectionList>

// Fetch asset collections of a single type and subtype provided (use PHCollectionListSubtypeAny to match all subtypes)
open class func fetchCollectionLists(with collectionListType: PHCollectionListType, subtype: PHCollectionListSubtype, options: PHFetchOptions?) -> PHFetchResult<PHCollectionList>

open class func fetchMomentLists(with momentListSubtype: PHCollectionListSubtype, containingMoment moment: PHAssetCollection, options: PHFetchOptions?) -> PHFetchResult<PHCollectionList>

open class func fetchMomentLists(with momentListSubtype: PHCollectionListSubtype, options: PHFetchOptions?) -> PHFetchResult<PHCollectionList>   

PHAsset

PHAsset是用來獲取圖片和視頻文件的元數(shù)據(jù)鱼辙,相當(dāng)于以前的 ALAsset,但比起ALAsset,PhotoKit 提供了額外的關(guān)于用戶資源的元數(shù)據(jù)廉嚼,而這些數(shù)據(jù)在以前使用 ALAssetsLibrary 框架中是沒有辦法訪問玫镐,或者很難訪問到倒戏。我們可以用PHAsset保存圖片和視頻資源對象, 然后展示或者修改它.它有幾個重要屬性:

mediaType :資源類型,圖片或者音頻或視頻

mediaType

mediaSubtypes :圖片又包含全景圖(Panorama)、HDR圖片恐似、屏幕截圖杜跷、livePhoto ,我們可以使用照片資源的 mediaSubtypes 屬性驗證資源庫中的圖像在捕捉時是否開啟了 HDR矫夷,拍攝時是否使用了相機應(yīng)用的全景模式.

Creation date 創(chuàng)建時間

Location 定位

Favorite 布爾值葛闷,用戶是否標(biāo)記資源為"收藏",我們平時瀏覽照片或視頻双藕,在下方點??就表示收藏這張圖淑趾。

hidden 要驗證一個資源是否被用戶標(biāo)記為收被隱藏,只要檢查 PHAsset 實例的 hidden 屬性即可忧陪。

sourceType : 資源可以來源自用戶相冊扣泊、iCloud、iTunes同步

SourceType

representsBurstburstSelectionTypes: 對于一個資源嘶摊,如果其 PHAsset 的 representsBurst 屬性為 true延蟹,則表示這個資源是一系列連拍照片中的代表照片 (多張照片是在用戶按住快門時拍攝的)。它還有一個屬性是 burstIdentifier叶堆,如果想要獲取連拍照片中的剩余的其他照片阱飘,可以通過將這個值傳入 fetchAssetsWithBurstIdentifier(...) 方法來獲取。用戶可以在連拍的照片中做標(biāo)記虱颗;此外沥匈,系統(tǒng)也會自動用各種試探來標(biāo)記用戶可能會選擇的潛在代表照片。這個元數(shù)據(jù)是可以通過 PHAsset 的 burstSelectionTypes 屬性來訪問忘渔。這個屬性是用三個常量組成的位掩碼:.UserPick 表示用戶手動標(biāo)記的資源高帖,.AutoPick 表示用戶可能標(biāo)記的潛在資源,.None 表示沒有標(biāo)記的資源辨萍。

burstSelectionTypes

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

PHAssetCollection

PHAssetCollection是一組有序的資源集合,包括相冊、moments锈玉、智能相冊以及共享照片流.它的重要屬性 爪飘;

assetCollectionType 資源集合類型,比如相冊或者“時刻”相冊

  typedef NS_ENUM(NSInteger, PHAssetCollectionType) {
    PHAssetCollectionTypeAlbum = 1,
    PHAssetCollectionTypeSmartAlbum = 2,
    PHAssetCollectionTypeMoment = 3,
  } 
  NS_ENUM_AVAILABLE_IOS(8_0);
  assetCollectionSubtype 子類型
  enum PHAssetCollectionType : Int { 
    case Album //從 iTunes 同步來的相冊拉背,以及用戶在 Photos 中自己建立的相冊 
    case SmartAlbum //經(jīng)由相機得來的相冊 
    case Moment //Photos 為我們自動生成的時間分組的相冊
  }

enum PHAssetCollectionSubtype : Int { 
  case AlbumRegular //用戶在 Photos 中創(chuàng)建的相冊 
  case AlbumSyncedEvent //使用 iTunes 從 Photos 照片庫或者 iPhoto 照片庫同步過來的事件师崎。然而,在iTunes 12 以及iOS 9.0 beta4上椅棺,選用該類型沒法獲取同步的事件相冊犁罩,而必須使用AlbumSyncedAlbum齐蔽。
  case AlbumSyncedFaces //使用 iTunes 從 Photos 照片庫或者 iPhoto 照片庫同步的人物相冊。
  case AlbumSyncedAlbum //做了 AlbumSyncedEvent 應(yīng)該做的事 
  case AlbumImported //從相機或是外部存儲導(dǎo)入的相冊床估,完全沒有這方面的使用經(jīng)驗含滴,沒法驗證。 
  case AlbumMyPhotoStream //用戶的 iCloud 照片流 
  case AlbumCloudShared //用戶使用 iCloud 共享的相冊 
  case SmartAlbumGeneric //文檔解釋為非特殊類型的相冊丐巫,主要包括從 iPhoto 同步過來的相冊谈况。 
  case SmartAlbumPanoramas //相機拍攝的全景照片 
  case SmartAlbumVideos //相機拍攝的視頻 
  case SmartAlbumFavorites //收藏文件夾 
  case SmartAlbumTimelapses //延時視頻文件夾,同時也會出現(xiàn)在視頻文件夾中 
  case SmartAlbumAllHidden //包含隱藏照片或視頻的文件夾 
  case SmartAlbumRecentlyAdded //相機近期拍攝的照片或視頻 
  case SmartAlbumBursts //連拍模式拍攝的照片  
  case SmartAlbumUserLibrary //這個命名最神奇了递胧,就是相機相冊碑韵,所有相機拍攝的照片或視頻都會出現(xiàn)在該相冊中,而且使用其他應(yīng)用保存的照片也會出現(xiàn)在這里缎脾。 
  case Any //包含所有類型
 }

estimatedAssetCount :估算的asset數(shù)量

PHFetchOptions

predicate : 做選擇的約束條件祝闻。比如,只獲取圖片遗菠,不獲取視頻联喘。指定 PHAssetMediaType為image.

  // swift:
  options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.Image.rawValue)
  sortDescriptors 可指定字段用來對獲取結(jié)果進行排序

includeHiddenAssets 獲取結(jié)果是否包括被隱藏的

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

  PHFetchOptions *options = [[PHFetchOptions alloc] init];
  options.wantsIncrementalChangeDetails = YES;
  options.includeAllBurstAssets = YES;
  options.includeHiddenAssets = YES;
  // 只取圖片
  options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d",PHAssetMediaTypeImage];
  // 按時間排序
  options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
  PHFetchResult *albums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumAllHidden options:nil];

PHFetchResult

類似數(shù)組,存儲獲取到asset對象集合舷蒲。同步快速獲取結(jié)果,即使結(jié)果集很大耸袜,框架也能保證獲取速度. 因為它不會一次性將所有結(jié)果放進內(nèi)存,而是按需批量加載,可以用類似 NSArray 的接口來訪問PHFetchResult結(jié)果內(nèi)的集合牲平。

資源對象的增刪改

API

(1) 創(chuàng)建PHAssetChangeRequest對象堤框。想要修改資源,需要創(chuàng)建一個PHAssetChangeRequest 纵柿。然后你就可以修改創(chuàng)建創(chuàng)建日期蜈抓,資源位置,以及是否將隱藏資源昂儒,是否將資源看做用戶收藏等沟使。此外,你還可以從用戶的庫里刪除資源渊跋。類似地腊嗡,若要修改資源集合或集合列表,需要創(chuàng)建一個 PHAssetCollectionChangeRequestPHCollectionListChangeRequest對象拾酝。然后你就可以修改集合標(biāo)題燕少,添加或刪除集合成員,或者完全刪除集合蒿囤。

(2) 操作的請求都要求在PHPhotoLibrary的performChanges的changeBlock中執(zhí)行

(3)如果有更新UI操作客们,需要遵守PHPhotoLibraryChangeObserver

協(xié)議,實現(xiàn)photoLibraryDidChange(changeInfo: PHChange!)方法.在photoLibraryDidChange中進行UI更新操作。

  PHPhotoLibrary.shared().performChanges({
        //新增、修改或刪除操作
    }) { (success, error) in
        //新增底挫、修改或刪除完成
    }

創(chuàng)建一個新資源只要用 creationRequestForAssetFromXXX(...)工廠方法恒傻,來創(chuàng)建變化請求,并傳入資源圖像數(shù)據(jù) (或一個 URL)建邓。如果你需要對新建的資源做額外的修改盈厘,你可以用創(chuàng)建變化請求的placeholderForCreatedAsset屬性。它會返回一個可用的 placeholder 來代替“真實的” PHAsset 引用.

PHPhotoLibrary

系統(tǒng)中PHPhotoLibrary單例對象 是用來維護用戶照片庫涝缝。當(dāng)我們需要編輯資源對象元數(shù)據(jù)扑庞、資源內(nèi)容譬重、或者插入新的資源對象等拒逮,都可以借助通過PHPhotoLibrary單例對象執(zhí)行block,block中創(chuàng)建我們指定的請求對象(比如PHAssetChangeRequest,PHAssetCollectionChangeRequest, PHCollectionListChangeRequest的對象)臀规。photoLibraryDidChange(changeInfo: PHChange!)中進行.

協(xié)議PHPhotoLibraryChangeObserver

PHPhotoLibraryChangeObserver協(xié)議能讓我們知道照片相冊庫中的改變滩援。Photos會發(fā)送系統(tǒng)圖片改變的消息,我們可以遵守PHPhotoLibraryChangeObserver協(xié)議塔嬉,并通過 PHPhotoLibrary的registerChangeObserver方法將對象注冊為觀察者玩徊,時時接收照片改變的消息。

PHChange

PHphoto框架會提供給我們PHChange對象谨究,我們可以調(diào)用changeDetailsForObject或者changeDetailsForFetchResult 方法恩袱,它返回給我們一個PHObjectChangeDetails對象,是對最新的照片實體對象的引用胶哲,可以告訴我們對象的圖像數(shù)據(jù)是否曾變化過畔塔、對象是否曾被刪除過。

請求圖片

  PHImageManager.default().requestImage(for: <#T##PHAsset#>, targetSize: <#T##CGSize#>, contentMode: <#T##PHImageContentMode#>, options: <#T##PHImageRequestOptions?#>, resultHandler: <#T##(UIImage?, [AnyHashable : Any]?) -> Void#>)  

targetSize: 返回圖片的尺寸
contentMode:決定了照片應(yīng)該以按比例縮放還是按比例填充的方式放到目標(biāo)大小內(nèi)鸯屿。
options: PHImageRequestOptions類用于定制請求澈吨。上面的方法返回指定尺寸的圖像,如果你僅僅指定必要的參數(shù)而沒有對 options 進行配置的話寄摆,返回的圖像尺寸將會是原始圖像的尺寸谅辣。或者婶恼,你指定的尺寸很小桑阶,這時候會按照你的要求來返回接近該尺寸的圖像。

PHImageRequestOptions

synchronous: 指定請求是否同步執(zhí)行勾邦。
resizeMode: 對請求的圖像怎樣縮放蚣录。有三種選擇:None,不縮放检痰;Fast包归,盡快地提供接近或稍微大于要求的尺寸;Exact,精準(zhǔn)提供要求的尺寸公壤。
deliveryMode: 圖像質(zhì)量换可。有三種值:Opportunistic,在速度與質(zhì)量中均衡厦幅;HighQualityFormat沾鳄,不管花費多長時間,提供高質(zhì)量圖像确憨;FastFormat译荞,以最快速度提供好的質(zhì)量。
normalizedCropRect: 用于對原始尺寸的圖像進行裁剪休弃,基于比例坐標(biāo)吞歼。只在 resizeMode 為 Exact 時有效。
resizeMode 默認是 None塔猾,這也造成了返回圖像尺寸與要求尺寸不符篙骡。這點需要注意。要返回一個指定尺寸的圖像需要避免兩層陷阱:一定要指定 options 參數(shù)丈甸,resizeMode 不能為 None糯俗。

是否裁剪圖片由 targetSize、contentMode來控制睦擂,裁剪的尺寸由targetSize得湘、contentMode、resizeMode指定顿仇。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末淘正,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子夺欲,更是在濱河造成了極大的恐慌跪帝,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件些阅,死亡現(xiàn)場離奇詭異伞剑,居然都是意外死亡,警方通過查閱死者的電腦和手機市埋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門黎泣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遂蛀,“玉大人勘究,你說我怎么就攤上這事∨欣颍” “怎么了坷澡?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵托呕,是天一觀的道長。 經(jīng)常有香客問我,道長项郊,這世上最難降的妖魔是什么馅扣? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮着降,結(jié)果婚禮上差油,老公的妹妹穿的比我還像新娘。我一直安慰自己任洞,他們只是感情好蓄喇,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著交掏,像睡著了一般妆偏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上耀销,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天楼眷,我揣著相機與錄音,去河邊找鬼熊尉。 笑死,一個胖子當(dāng)著我的面吹牛掌腰,可吹牛的內(nèi)容都是我干的狰住。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼齿梁,長吁一口氣:“原來是場噩夢啊……” “哼催植!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起勺择,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤创南,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后省核,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體稿辙,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年气忠,在試婚紗的時候發(fā)現(xiàn)自己被綠了邻储。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡旧噪,死狀恐怖吨娜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情淘钟,我是刑警寧澤宦赠,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響勾扭,放射性物質(zhì)發(fā)生泄漏缤骨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一尺借、第九天 我趴在偏房一處隱蔽的房頂上張望绊起。 院中可真熱鬧,春花似錦燎斩、人聲如沸虱歪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笋鄙。三九已至,卻和暖如春怪瓶,著一層夾襖步出監(jiān)牢的瞬間萧落,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工洗贰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留找岖,地道東北人。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓敛滋,卻偏偏與公主長得像许布,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子绎晃,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

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