在前面的文章中氛雪,我們已經(jīng)介紹了各種媒體獲取的方式房匆,還沒介紹如何將這些媒體資源保存到相冊中。本篇文章的保存方式是基于PHPhotoLibrary
這個(gè)系統(tǒng)類的报亩,下面將簡單介紹保存使用的部分浴鸿,其他功能詳細(xì)請參見官方文檔。
媒體獲取方式傳送門:
媒體類型
在自定義相機(jī)中弦追,我們獲取的媒體類型有以下三種岳链,分別是靜態(tài)照片、動(dòng)態(tài)照片和視頻骗卜。他們在捕獲后的資源存在形式如下:
- 靜態(tài)照片:NSData
- 動(dòng)態(tài)照片:NSData + NSURL
- 視頻:NSURL
因此,我們向系統(tǒng)相冊寫入數(shù)據(jù)都是圍繞著NSData
和NSURL
進(jìn)行的左胞。
權(quán)限問題
和獲取相機(jī)寇仓、相冊、麥克風(fēng)數(shù)據(jù)一樣烤宙,向系統(tǒng)相冊寫入數(shù)據(jù)也需要獲取權(quán)限遍烦。在Info.plist
中我們需要添加:
<key>NSPhotoLibraryAddUsageDescription</key>
<string>App需要您的同意,才能添加圖片</string>
由于需要獲取權(quán)限,我們在開發(fā)的時(shí)候就需要像打開相機(jī)一樣小心躺枕,操作前務(wù)必檢查權(quán)限服猪,避免出現(xiàn)不好的用戶體驗(yàn)。
PHPhotoLibrary 寫入數(shù)據(jù)
我們需要先通過[PHPhotoLibrary sharedPhotoLibrary]
獲取PHPhotoLibrary
的單例對象拐云,再調(diào)用核心方法performChanges:completionHandler:
罢猪。該方法用于向相冊中異步寫入資源數(shù)據(jù),所以開發(fā)者只需要把寫入數(shù)據(jù)的操作放在Changes
中叉瘩,完成回調(diào)放在completionHandler
中即可膳帕。
Changes 操作
Changes
操作由系統(tǒng)異步調(diào)用,PHPhotoLibrary
規(guī)定我們在寫入數(shù)據(jù)時(shí)候薇缅,需要使用PHAssetCreationRequest
對象進(jìn)行操作危彩。主要分為以下兩步走:
-
創(chuàng)建步驟:使用
creationRequestForAsset
類方法進(jìn)行對象的創(chuàng)建 -
配置步驟:使用
addResourceWithType:fileURL:options:
或addResourceWithType:data:options:
配置需要保存的資源
不同類型媒體資源的保存只需要需要使用不同的type
和資源組合即可攒磨,代碼如下:
靜態(tài)照片 - Photo
PHAssetCreationRequest *imageRequest = [PHAssetCreationRequest creationRequestForAsset];
[imageRequest addResourceWithType:PHAssetResourceTypePhoto data:imageData options:nil];
PS:可以使用可以將需要保存UIImage
通過UIImageJPEGRepresentation
或UIImagePNGRepresentation
方法轉(zhuǎn)成需要的imageData
。
動(dòng)態(tài)照片 - Photo + PairedVideo
PHAssetCreationRequest* creationRequest = [PHAssetCreationRequest creationRequestForAsset];
[creationRequest addResourceWithType:PHAssetResourceTypePhoto data:imageData options:nil];
PHAssetResourceCreationOptions* resourceOptions = [[PHAssetResourceCreationOptions alloc] init];
resourceOptions.shouldMoveFile = YES;
[creationRequest addResourceWithType:PHAssetResourceTypePairedVideo fileURL:filmURL options:resourceOptions];
PS:動(dòng)態(tài)照片的視頻部分類型必須是PHAssetResourceTypePairedVideo
表示該視頻是整個(gè)資源的一部分汤徽,那么系統(tǒng)將會(huì)將其與同時(shí)傳入的照片一起合成動(dòng)態(tài)照片娩缰。
視頻 - Video
PHAssetCreationRequest *videoRequest = [PHAssetCreationRequest creationRequestForAsset];
PHAssetResourceCreationOptions* resourceOptions = [[PHAssetResourceCreationOptions alloc] init];
resourceOptions.shouldMoveFile = YES;
[videoRequest addResourceWithType:PHAssetResourceTypeVideo fileURL:fileURL options:resourceOptions];
PS:這里和動(dòng)態(tài)照片中的視頻一樣都使用了options
,它是一個(gè)PHAssetResourceCreationOptions
對象谒府,可用于定義存入文件的文件名(originalFilename
)拼坎、文件類型(uniformTypeIdentifier
)和是否在寫入后刪除(shouldMoveFile
)。
組合操作
由于將資源寫入相冊需要權(quán)限狱掂,因此每次在寫入的時(shí)候我們都應(yīng)該像下方的代碼一樣先處理權(quán)限問題演痒,再處理寫入問題:
+ (void)customSaveWithChangeBlock:(dispatch_block_t)changeBlock
authHandle:(SCPhotosSaveAuthHandle)authHandle
completion:(SCPhotosSaveCompletion)completion {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status != PHAuthorizationStatusAuthorized) {
dispatch_async(dispatch_get_main_queue(), ^{
if (authHandle)
authHandle(false, status);
});
return;
}
[[PHPhotoLibrary sharedPhotoLibrary]
performChanges: changeBlock
completionHandler:^(BOOL success, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (completion)
completion(success, error);
});
}];
}];
}
最后:我將文章中三種媒體類型的保存方式都封裝在分類中,大家可以直接查閱PHPhotoLibrary+Save.h進(jìn)行使用趋惨。