什么是PhotoKit
PhotoKit是iOS 8.0后蘋果提供給開發(fā)者使用管理、訪問系統(tǒng)的圖片資源和視頻資源的框架。使用PhotoKit,開發(fā)者可以獲取和緩存assets(資源)用來顯示和播放,編輯圖片和視頻的內(nèi)容,或者管理aseets的集合,比如相冊、精彩時(shí)刻、或者共享相冊。

PhotoKit中重要的類
- PHAsset: 單個(gè)資源,可以是照片/視頻/動態(tài)圖片
- PHCollection:PHAssetCollection和PHCollectionList的抽象類
- PHAssetCollection:PHCollection的子類,單個(gè)資源的集合,如相冊、時(shí)刻等
- PHCollectionList:PHCollection的子類,集合的集合,如相冊文件夾
- PHPhotoLibrary:類似于總管理,負(fù)責(zé)注冊通知、檢查和請求獲取權(quán)限
- PHImageManager:按照要求獲取指定的圖片的管理者
- PHCachingImageManager:PHImageManager的子類
- PHAssetResourceManager:專門用于Photos資源存儲的管理類
- PHAssetChangeRequest:編輯相冊,增刪改查
- PHFetchResult: 一個(gè)保存PHAsset或者PHCollection的數(shù)組
關(guān)系圖如下:

主要API
PHCollection
該類有兩個(gè)類方法:
// 根據(jù)指定的PHCollectionList獲取PHCollection集合
class func fetchCollections(in: PHCollectionList, options: PHFetchOptions?) -> PHFetchResult<PHCollection>
// 從照片庫的用戶創(chuàng)建的相冊和文件夾的層次結(jié)構(gòu)中檢索集合。
class func fetchTopLevelUserCollections(with: PHFetchOptions?) -> PHFetchResult<PHCollection>
PHAssetCollection
一個(gè)該實(shí)例對象代表一個(gè)相冊,是PHCollection的子類。它的所有屬性都是只讀的,另外有8個(gè)類方法,用來獲取想要的結(jié)果。
class func fetchAssetCollections(with type: PHAssetCollectionType,
subtype: PHAssetCollectionSubtype,
options: PHFetchOptions?) -> PHFetchResult<PHAssetCollection>
Demo代碼:利用PHAssetCollection獲取Assets資源
private func startFetch() {
let options = PHFetchOptions()
options.predicate = self.predicate()
if let collect = PHAssetCollection.fetchAssetCollections(with: .smartAlbum,
subtype: .smartAlbumUserLibrary,
options: nil).firstObject {
fetchResult = PHAsset.fetchAssets(in: collect, options: options)
} else {
fetchResult = PHFetchResult<PHAsset>()
}
self.imageManager = PhotoScrollPickerImageManager()
PHPhotoLibrary.shared().register(self)
}
該方法是該類的主要訪問方法,主要用于在未知相冊的情況下,直接通過type和subtype從相冊獲取相應(yīng)的相冊。type和subtype如下所示:
Photos type
PHAssetCollectionType
enum PHAssetCollectionType : Int {
case Album // 從 iTunes 同步來的相冊,以及用戶在 Photos 中自己建立的相冊
case SmartAlbum // 經(jīng)由相機(jī)得來的相冊
case Moment // Photos 為我們自動生成的時(shí)間分組的相冊
}
PHAssetCollectionSubtype
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 //從相機(jī)或是外部存儲導(dǎo)入的相冊,完全沒有這方面的使用經(jīng)驗(yàn),沒法驗(yàn)證。
case AlbumMyPhotoStream //用戶的 iCloud 照片流
case AlbumCloudShared //用戶使用 iCloud 共享的相冊
case SmartAlbumGeneric //文檔解釋為非特殊類型的相冊,主要包括從 iPhoto 同步過來的相冊。由于本人的 iPhoto 已被 Photos 替代,無法驗(yàn)證。不過,在我的 iPad mini 上是無法獲取的,而下面類型的相冊,盡管沒有包含照片或視頻,但能夠獲取到。
case SmartAlbumPanoramas //相機(jī)拍攝的全景照片
case SmartAlbumVideos //相機(jī)拍攝的視頻
case SmartAlbumFavorites //收藏文件夾
case SmartAlbumTimelapses //延時(shí)視頻文件夾,同時(shí)也會出現(xiàn)在視頻文件夾中
case SmartAlbumAllHidden //包含隱藏照片或視頻的文件夾
case SmartAlbumRecentlyAdded //相機(jī)近期拍攝的照片或視頻
case SmartAlbumBursts //連拍模式拍攝的照片,在 iPad mini 上按住快門不放就可以了,但是照片依然沒有存放在這個(gè)文件夾下,而是在相機(jī)相冊里。
case SmartAlbumSlomoVideos //Slomo 是 slow motion 的縮寫,高速攝影慢動作解析,在該模式下,iOS 設(shè)備以120幀拍攝。不過我的 iPad mini 不支持,沒法驗(yàn)證。
case SmartAlbumUserLibrary //這個(gè)命名最神奇了,就是相機(jī)相冊,所有相機(jī)拍攝的照片或視頻都會出現(xiàn)在該相冊中,而且使用其他應(yīng)用保存的照片也會出現(xiàn)在這里。
case Any //包含所有類型
PHCollectionListType
typedef NS_ENUM(NSInteger, PHCollectionListType) {
PHCollectionListTypeMomentList = 1, // 包含了PHAssetCollectionTypeMoment類型的資源集合的列表
PHCollectionListTypeFolder = 2, // 包含了PHAssetCollectionTypeAlbum類型或PHAssetCollectionTypeSmartAlbum類型的資源集合的列表
PHCollectionListTypeSmartFolder = 3, // 同步到設(shè)備的智能文件夾的列表
} PHOTOS_ENUM_AVAILABLE_IOS_TVOS(8_0, 10_0);
PHCollectionListSubtype
typedef NS_ENUM(NSInteger, PHCollectionListSubtype) {
// PHCollectionListTypeMomentList的子類型
PHCollectionListSubtypeMomentListCluster = 1, // 時(shí)刻
PHCollectionListSubtypeMomentListYear = 2, // 年度
// PHCollectionListTypeFolder的子類型
PHCollectionListSubtypeRegularFolder = 100, // 包含了其他文件夾或者相簿的文件夾
// PHCollectionListTypeSmartFolder的子類型
PHCollectionListSubtypeSmartFolderEvents = 200, // 包含了一個(gè)或多個(gè)從iPhone同步的事件的智能文件夾
PHCollectionListSubtypeSmartFolderFaces = 201, // 包含了一個(gè)或多個(gè)從iPhone同步的面孔(人物)的智能文件夾
// 如果你不關(guān)心子類型是什么,則使用下面這個(gè)
PHCollectionListSubtypeAny = NSIntegerMax
} PHOTOS_ENUM_AVAILABLE_IOS_TVOS(8_0, 10_0);
PHCollectionEditOperation
typedef NS_ENUM(NSInteger, PHCollectionEditOperation) {
PHCollectionEditOperationDeleteContent = 1, // 刪除集合中包含的內(nèi)容,刪除的東西會永久的從照片庫中刪除
PHCollectionEditOperationRemoveContent = 2, // 移除集合中包含的內(nèi)容,但移除的東西不會從照片庫中刪除
PHCollectionEditOperationAddContent = 3, // 從其他的集合中添加內(nèi)容
PHCollectionEditOperationCreateContent = 4, // 創(chuàng)建新的內(nèi)容或者從其他的容器中復(fù)制內(nèi)容到這個(gè)容器中
PHCollectionEditOperationRearrangeContent = 5, // 改變內(nèi)容的順序
PHCollectionEditOperationDelete = 6, // 刪除容器但不刪除內(nèi)容
PHCollectionEditOperationRename = 7, // 重命名容器的名字
} PHOTOS_AVAILABLE_IOS_TVOS(8_0, 10_0);
PHPhotoLibrary
一個(gè)單例對象,用于管理對用戶照片庫的訪問和更改。PHPhotoLibrary代表了由Photos應(yīng)用程序管理的整套媒體資源和集合,包括存儲在本地設(shè)備上的asset和存儲在iCould Photos中的assets(如果用戶已經(jīng)開啟iCould)。可以通過這個(gè)對象來:
- 獲取或者驗(yàn)證用戶對當(dāng)前App訪問照片內(nèi)容的權(quán)限
- 對asset和媒體資源集合進(jìn)行管理,比如:編輯asset元數(shù)據(jù)或內(nèi)容,插入新的asset或者重新排列集合的成員
- 注冊某個(gè)類作為當(dāng)library發(fā)生改變時(shí)候的接受者
PHFetchResult
從某個(gè)獲取Aseet的方法返回的有序的asset或者collections的列表(可以理解為一個(gè)數(shù)組)
PHAsset
該類表示具體的資源信息,如寬度、高度、時(shí)長、是否是收藏的等等。同上面提到的幾個(gè)類一樣,該類的屬性也都是只讀的,所以我們主要是用它的方法來獲取資源。
// 用來判斷該資源是否可以做某些操作,比如增刪改查。也從另一個(gè)方面暗示了,
// 在對該資源做一些操作之前有必要先做一下判斷,這可以省去一些不必要的麻煩。
func canPerform(PHAssetEditOperation) -> Bool
// 該方法是從相冊中獲取單個(gè)資源的主要途徑
class func fetchAssets(in assetCollection: PHAssetCollection, options: PHFetchOptions?) -> PHFetchResult<PHAsset>
PHImageManager
便于檢索或生成預(yù)覽縮略圖和asset數(shù)據(jù)的對象。
PHAssetResourceManager
Assets可以具有多個(gè)基礎(chǔ)數(shù)據(jù)資源 - 例如,原始版本和編輯版本 - 每個(gè)都由PHAssetResource對象表示。 與PHImageManager類不同,PHImageManager類以縮略圖,圖像對象或視頻對象的形式提供和緩存資產(chǎn)的主要表示,PHAssetResourceManager提供對這些底層數(shù)據(jù)資源的直接訪問。
主要方法
// 獲取一個(gè)單例對象
class func `default`() -> PHAssetResourceManager
// 異步請求指定資產(chǎn)資源的基礎(chǔ)數(shù)據(jù)
func requestData(for: PHAssetResource,
options: PHAssetResourceRequestOptions?,
dataReceivedHandler: (Data) -> Void,
completionHandler: (Error?) -> Void) -> PHAssetResourceDataRequestID
// 取消異步請求
func cancelDataRequest(PHAssetResourceDataRequestID)
// 請求Asset的基礎(chǔ)數(shù)據(jù),異步寫入本地文件
func writeData(for: PHAssetResource,
toFile: URL,
options: PHAssetResourceRequestOptions?,
completionHandler: (Error?) -> Void)
Assets存儲
Assets的存儲方式主要有以下幾種:
- 利用PHAssetResourceManager進(jìn)行存儲
- 利用Data進(jìn)行存儲
- 利用FileManager進(jìn)行存儲