簡介數組
Photos framework是iOS8蘋果提供的新的圖片框架,能直接獲取圖片和視頻,包括iCloud上面的圖庫。使用這個框架能夠獲取assets來展現和回放,編輯圖片或者視頻內容,或者使用系統相冊、時刻、和分享到iCloud的相冊來進行相關操做,本文側重相片的獲取與保存。 demo地址在這裏緩存
新特性與一些概念app
獲取實體&改變請求: Photos framework中的三個model類:PHAsset,PHAssetCollection,PHCollectionList,分別對應三個類型的實體:asset(圖片和視頻),assets集合(相冊和時刻),集合列表(相冊文件夾或者moment clusters)。這些對象,也成爲 相片實體(photo entities),只包含元數據,同時也是read-only屬性。框架
改變觀察機制: 使用這個特性可以在其餘app、設備更改了圖片和視頻內容或者相冊的時候通知你的app,在實現觀察機制前須要用PHPhotoLibrary對象先爲你獲取到的照片實體註冊一個觀察者異步
支持手機中的照片app的特性 使用PHCollectionList類查找獲取照片中響應的時刻層級asset,使用PHAsset標記連拍照片,全景照片和高分辨率視頻等。當開啓iCloud圖庫後,Photo framework能從iCloud中獲取到使用相同apple ID登錄的不一樣設備中的照片。ide
加載緩存asset和縮略圖 使用PHImageManager請求asset中的特定尺寸的圖片或者經過AV Foundation 對象獲取video asset。Photos frame會根據設定自動下載,緩存,以便於高效複用。對於大量的assets的快速執行,例如在生成相冊中全部圖片的縮略圖時,使用PHCachingImageManager的子類來實現。性能
編輯asset內容 PHAsset和PHAsssetChangeRequest定義了一些用於編輯照片或者視頻內容的方法,同時容許將編輯後的圖片保存到圖庫中。爲了可讓用戶能夠在前次修改的基礎上再次修改,或者是在不一樣的app上進行屢次修改,Photos保存了當前和縣區版本的asset,若是單獨使用PHAdjustMnentData對象只能獲取到最後編輯的照片。若是你的app支持在前面修改基礎上屢次編輯,你應該容許用戶撤回或者修改本次編輯。fetch
framework中的類atom
PHAdjustmentData.net
當修改了一個asset後,Photos會將PHAdjustmentData對象和修改過的圖片或者視頻數據一塊兒保存起來,你能夠經過這個對象提供的一些數據來修改已經保存的編輯。
當須要調整data的時候,調用
/**
*/
在圖庫中使用PHAssetChangeRequest對象來建立,修改,刪除PHAsset對象。
可使用適當的類方法來實現增長刪除修改asset的目的:
/**
/**
當你使用沒方法獲取PHAsset(圖片和視頻),PHCollection(相冊類型),PHAssetCollection(相冊)的實體(至關於包含多個數據的模型)使用PHFetchOptions對象指定操做,例如獲取的實體的排列屬性等。
調用PHFetchRequest類方法建立一個包含fetch請求的對象。
這個類包含了兩個屬性:predicate和sortDescriptors。
NSPredicate *predicate:
specifies which properties to select results by and that also specifies any constraints on selection. 用於指定返回的結果和指定條件
示例:
PHFetchOperation *fetchOptions = [PHFetchOption new]; fetchOperations.predicate = [NSPredicate predicateWithFormat: @"(mediaSubtype & %d) != 0 || (mediaSubtype & %d) != 0", PHAssetMediaSubtypePhotoPanorama,PHAssetMediaSubtypeVideoHightFrameRate];
PHFetchResult *result = [PHAsset fetchAssetWithOptions:fetchOptions]; NSArray <NSSortDescriptor *> *sortDescriptors 用於指定獲取的對象的順序 用一個例子實現以時間順序倒序(剛拍攝的照片放在前頭排列獲取圖片的功能:
PHFetchOption *option = [PHFetchOption new]; option.sourtDescriptors = @[NSSortDescriptors sortDescriptiorWithKey:@"creationDate" ascending:NO]; PHFetchResult *result = [PHAsset fetchAssetsWithOptions:option]; 其餘幾個屬性:
//用於肯定app是否接收到了具體的改變信息。 @property(nonatomic, assign) BOOL wantsIncrementalChangeDetails
/** *限制檢索獲取獲得的photo實體的最小數量,當實體數量十分巨大時,做用顯著, *例如,用'PHAsset'的'fetchAssetsWithOptions:'方法獲取最近拍攝的照片等。 */ @property(nonatomic, assign, readwrite) NSUInteger fetchLimit
//檢索結果是否包含連拍圖片,若是是NO,只顯示用戶選取的那種圖片,若是爲YES, @property(nonatomic, assign) BOOL includeAllBurstAssets
//顧名思義,是否檢索隱藏的圖片 @property(nonatomic, assign) BOOL includeHiddenAssets
/** *包含的數據類型: *PHAssetSourceTypeUserLibrary
*PHAssetSourceTypeCloudShared *PHAssetSourceTypeiTunesSynced */ @property(nonatomic, assign) PHAssetSourceType includeAssetSourceTypes PHImageRequestOption
PHImageRequestOption 用於配置從PHImageManager中獲取asset的請求。 經常使用的一些屬性和方法有:
/**
/** *typedef : NSInteger { PHImageRequestOptionsDeliveryModeOpportunistic = 0, PHImageRequestOptionsDeliveryModeHighQualityFormat = 1, PHImageRequestOptionsDeliveryModeFastFormat = 2, } PHImageRequestOptionsDeliveryMode;
*@PHImageRequestOptionsDeliveryModeOpportunistic: 自動返回一個或多個結果,來平衡圖片的質量和響應性,它會屢次調用 resutltHandler:'requestImageForAssets:targetSize:options:resultHandler'. 它首先會先調用一次'resutltHandler'返回清晰度低的圖片做爲臨時顯示圖片, 等到能獲取到高清晰度的圖片時再次調用'resutltHandler'返回高質量圖片。
note:若是'synchronous'是NO那麼該屬性無效
*@PHImageRequestOptionsDeliveryModeHighQualityFormat 只返回高分辨率的圖片。具備較高的優先權
*@PHImageRequestOptionsDeliveryModeFastFormat 快速返回結果,可能會犧牲圖片質量。 */ @property (nonatomic, assign) PHImageRequestOptionsDeliveryMode deliveryMode;
/**
/**
/** 下載進度block,在多條線程中執行操做,刷新UI時須要回到主線程
*/ typedef void (^ PHAssetImageProgressHandler)(double progress, NSError *error, BOOL *stop, NSDictionary *info);
@property(nonatomic, copy) PHAssetImageProgressHandler progressHandler PHFetchResult
PHFetchRequest是有序的photo實體對象的容器,包含經過給定的檢索條件返回的asset,相冊,一個相冊類型中的全部相冊列表(例如,smart album類型下的全部相冊,它是有序的),在PHAsset,PHCollection,PHAssetcollection,PHCollectionList這幾個類中都包含有相應的類方法包含對應信息的PHFetchRequest對象,例如:
PHAsset
/**
aaset類型,包含有:
PHAssetMediaTypeUnknown = 0,
PHAssetMediaTypeImage,
PHAssetMediaTypeVideo,
PHAssetMediaTypeAudio,
//Retrieves collections from the root of the photo library’s hierarchy of user-created albums and folders. +(PHFetchResult<PHCollection *> *)fetchTopLevelUserCollectionsWithOption:(PHFetchOptions *)options; PHAssetCollection:
/**
獲取自定條件的相冊
@param type 相冊類型: PHAssetCollectionTypeAlbum PHAssetCollectionTypeSmartAlbum PHAssetCollectionTypeMoment
@param subtype 相對於相冊類型更具體些的相片類型,如全景,照片流等
@param options 檢索條件
@return 符合條件的相冊 */ +(PHFetchResult<PHAssetCollection *> *)fetchAssetColletcionsWithType:(PHAssetCollectionType)type subtype:(PHAssetCollectionSubtype)subtype options:(PHFetchOptions *)options; PHCollectionList: +(PHFetchResult<PHCollectionList *> *)fetchCollectionListsWithType:(PHCollectionListType)collectionListType subtype:(PHCollectionListSubtype)subtype options:(PHFetchOptions *)options PHFetchRequest雖然包含了符合條件的photo實體的集合,與NSArray不一樣的是它會動態改變包含的內容,在處理大量的asset的時候效率更高些,實現的效果也好點
經常使用屬性與方法
//是否包含給定的對象
//包含的photo實體個數 @property(readonly) NSUInteger count
//指定類型的asset數量
PHImageManager有一個單例方法,同時也提供了用於獲取全尺寸圖片,圖片縮略圖等方法.
獲取圖片:
/**
/**
(PHImageRequestID)requestImageDataForAsset:(PHAsset *)asset options:(PHImageRequestOptions *)options resultHandler:(void (^)(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info))resultHandler; 取消請求:
(void)cancelImageRequest:(PHImageRequestID)requestID PHCachingImageManager
PHCachingImageManager是PHImageManager的子類,若是相冊中有大量的圖片,而你的需求是要快速的獲取這些圖片的縮略圖和大圖數據用於展現,這個時候能夠用PHCachingImageManager來實現,它具備緩存機制能夠快速獲取一個圖冊的縮略圖,或者在後臺請求全尺寸圖片以便於快速展現。
開始緩存圖片:
/**
/**
PHPhotoLibrary能夠當作是一個用戶圖庫,包含了一些的圖片和相冊,同時包含本地的和iCloud中的資源。當Photos app發生圖片的修改、增長、刪除等改變時,使用PHPhotoLibrary來作一些刷新UI,保存數據等響應動做,同時也能夠註冊觀察者(使用registerChangeObserver方法),當Photos app內容發生改變的時,會觸發代理方法photoLibraryDidChange。
使用PHPhotoLibrary響應圖庫改變
Photos中的PHAsset,PHAssetCollection等是不可變對象,所以要改變當前這些類型對象的時候就須要使用photo library實現改變。
請求改變數據須要用到PHAssetChangeRequest,PHAssetcCollectionChangeRequest,PHCollectionListChangeRequest。
使用步驟:
一、建立實體
每一個change request類都提供了用於建立響應的實體類的方法: creationRequestForAssetCollectionWithTitle:建立了一個asset Collection
若是要添加一個新的asset到collection中,須要用到change request提供的PHObjectPlaceholder對象。在change block結束以後,使用placeholder對象提供的localIdentifier屬性獲取建立好的asset對象。
二、刪除實體
例如:deleCollectionLists用於刪除collection list
三、修改實體
changeRqeustForAsset建立了一個可用於修改的asset的change request
下面代碼實現往相冊中添加新圖片的功能:
(void)addNewAssetWithImge:(UIImage *)image toAlbum:(PHAssetCollection *)album {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetChange = [PHAssetChangeRequest creationRequestForAssetFromImage:image]; PHAssetCollectionChangeRequest *collectionChange = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album]; PHObjectPlaceholder *placeholder = [assetChange placeholderForCreatedAsset]; [collectionChange addAssets:@[placeholder]];
} completionHandler:^(BOOL success, NSError * _Nullable error) { NSLog(@"Finished adding asset. %@", (success ? @"Success" : error)); }]; } note:For each call to the performChanges:completionHandler: or performChangesAndWait:error: method, iOS shows an alert asking the user for permission to edit the contents of the photo library. 註冊觀察者
PHPhotoLibraryChangeObserver在系統圖庫發生變化的時候就會通知指定的觀察者,只要是使用了Photos framework實現的改變,都會觸發觀察者的方法。 registerChangeObserver:方法指定一名觀察者,當系統圖庫發生改變,會觸發觀察者的指定方法,這個方法在PHPhotoLibraryChangeObserver協議中:- (void)photoLibraryDidChange:(PHChange *)changeInfo ;
PHCollection
PHCollection是一個抽象類,不容許直接使用它的實例對象,而是使用它的兩個子類:PHAssetCollection,PHCollectionList: PHAssetCollection 包含了帶有圖片或者視頻信息PHAsst對象,PHCollectionList能夠看作是一個文件夾,裏面存放多個相冊或者是在年度相冊中的全部時刻的照片。
獲取圖片集合:
//用特定的操做從collection list中獲取collection集合
//獲取全部用戶建立的相冊或者文件夾。
一個PHAssetCollection表明一個相冊,可能包含圖片和視頻,例如:時間相冊,個人照片流,自拍。
在Photos framework中不能直接獲取collection中的內容,經過fetchAssetsInAssetCollecton:options:獲取到包含PHAsset集合的PHFecthReult對象,以後用fetchResult提供的方法取出圖片或者視頻。
獲取asset collection 的方法有許多種:
/**
@param type 相冊類型: PHAssetCollectionSubtypeAlbumRegular Photos APP中建立的相冊
PHAssetCollectionSubtypeAlbumSyncedEvent 從iPhoto中同步的事件相冊 PHAssetCollectionSubtypeAlbumSyncedFaces 從iPhoto中同步的包含人臉的相冊 PHAssetCollectionSubtypeAlbumSyncedAlbum 從iPhoto同步的普通相冊 PHAssetCollectionSubtypeAlbumImported 從其餘設備導入的相冊 PHAssetCollectionSubtypeAlbumCloudShared 分享到iCloud的照片流相冊 PHAssetCollectionSubtypeAlbumMyPhotoStream 用戶我的的iCloud照片流 PHAssetCollectionSubtypeSmartAlbumGeneric 沒有特定類型的只能相冊 PHAssetCollectionSubtypeSmartAlbumPanoramas 全景圖片相冊 PHAssetCollectionSubtypeSmartAlbumVideos 視頻相冊 PHAssetCollectionSubtypeSmartAlbumFavorites 我的收藏 PHAssetCollectionSubtypeSmartAlbumTimelapses 延時攝影相冊 PHAssetCollectionSubtypeSmartAlbumAllHidden 隱藏的圖片相冊 PHAssetCollectionSubtypeSmartAlbumRecentlyAdded 最近添加的圖片 PHAssetCollectionSubtypeSmartAlbumBursts 連拍相冊 PHAssetCollectionSubtypeSmartAlbumSlomoVideos 慢動做視頻相冊 PHAssetCollectionSubtypeSmartAlbumUserLibrary 在本地存在的相冊(不包含icloud中的相冊) PHAssetCollectionSubtypeSmartAlbumSelfPortraits 自拍 PHAssetCollectionSubtypeSmartAlbumScreenshots 截屏 PHAssetCollectionSubtypeAny 獲取全部類型的相冊
@param options 篩選操做
@return 包含符合條件的相冊的fetch result */
/**
*/
PHCollectionList包含了更高級別的asset集合,可嵌套PHAssetCollection 和自身類型,還支持多重嵌套,例如獲取時刻相冊和時刻相冊中年度照片等。
獲取collection list的幾種方法:
(PHFetchResult<PHCollectionList *>)fetchCollectionListsContainingCollection:(PHCollection *)collection options:(PHFetchOptions *)options;
(PHFetchResult<PHCollectionList *> *)fetchCollectionListsContainingCollection:(PHCollection *)collection options:(nullable PHFetchOptions *)options;
(PHFetchResult<PHCollectionList *> *)fetchCollectionListsWithLocalIdentifiers:(NSArray<NSString *> *)identifiers options:(nullable PHFetchOptions *)options;
(PHFetchResult<PHCollectionList *> *)fetchCollectionListsWithType:(PHCollectionListType)collectionListType subtype:(PHCollectionListSubtype)subtype options:(nullable PHFetchOptions *)options;
(PHFetchResult<PHCollectionList *> *)fetchMomentListsWithSubtype:(PHCollectionListSubtype)momentListSubtype containingMoment:(PHAssetCollection *)moment options:(nullable PHFetchOptions *)options;
(PHFetchResult<PHCollectionList *> *)fetchMomentListsWithSubtype:(PHCollectionListSubtype)momentListSubtype options:(nullable PHFetchOptions *)options; PHAsset
PHAsset表明一個視頻或者圖片資源,當須要展現或者修改Photos app中的圖片時須要先獲取asset,asset是不可改變的而且只保存了所表明的視頻或者圖片的metadata。
獲取PHAsset的幾種方法:
//從asset collection中獲取符合條件的asset集合
/**
默認返回全部類型的asset,若是要給asset添加更多的類型限定,能夠在options的filter predicate中設置。
@param mediaType : PHAssetMediaTypeUnknown 未知類型
PHAssetMediaTypeImage 靜態圖片 PHAssetMediaTypeVideo 視頻 PHAssetMediaTypeAudio 音頻
注: PHMediaSubtype:
PHAssetMediaSubtypeNone = 0, // Photo subtypes PHAssetMediaSubtypePhotoPanorama = (1UL << 0), PHAssetMediaSubtypePhotoHDR = (1UL << 1), PHAssetMediaSubtypePhotoScreenshot NS_AVAILABLE_IOS(9_0) = (1UL << 2), PHAssetMediaSubtypePhotoLive NS_AVAILABLE_IOS(9_1) = (1UL << 3), // Video subtypes PHAssetMediaSubtypeVideoStreamed = (1UL << 16), PHAssetMediaSubtypeVideoHighFrameRate = (1UL << 17), PHAssetMediaSubtypeVideoTimelapse = (1UL << 18),
*/
(PHFetchResult <PHAsset *> *_Nullable)fetchAssetsWithMediaType:(PHAssetMediaType)mediaType options:(PHFetchOptions *_Nullable)options;
(PHFetchResult *<PHAsset *> *)fetchAssetsWithLocalIndentifiers:(NSArray <NSString *>)identifier options:(PHFetchOptions *)options;
/**
/**
//獲取連拍照片