cdts/xdts-ios 3/TreeHole/CYHResetCode/CYH/QMUIKit/QMUIComponents/AssetLibrary/QMUIAssetsManager.m

396 lines
22 KiB
Mathematica
Raw Normal View History

2023-07-27 09:20:00 +08:00
/**
* Tencent is pleased to support the open source community by making QMUI_iOS available.
* Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
//
// QMUIAssetsManager.m
// qmui
//
// Created by QMUI Team on 15/6/9.
//
#import "QMUIAssetsManager.h"
#import "QMUICore.h"
#import "QMUIAsset.h"
#import "QMUILog.h"
void QMUIImageWriteToSavedPhotosAlbumWithAlbumAssetsGroup(UIImage *image, QMUIAssetsGroup *albumAssetsGroup, QMUIWriteAssetCompletionBlock completionBlock) {
[[QMUIAssetsManager sharedInstance] saveImageWithImageRef:image.CGImage albumAssetsGroup:albumAssetsGroup orientation:image.imageOrientation completionBlock:completionBlock];
}
void QMUISaveImageAtPathToSavedPhotosAlbumWithAlbumAssetsGroup(NSString *imagePath, QMUIAssetsGroup *albumAssetsGroup, QMUIWriteAssetCompletionBlock completionBlock) {
[[QMUIAssetsManager sharedInstance] saveImageWithImagePathURL:[NSURL fileURLWithPath:imagePath] albumAssetsGroup:albumAssetsGroup completionBlock:completionBlock];
}
void QMUISaveVideoAtPathToSavedPhotosAlbumWithAlbumAssetsGroup(NSString *videoPath, QMUIAssetsGroup *albumAssetsGroup, QMUIWriteAssetCompletionBlock completionBlock) {
[[QMUIAssetsManager sharedInstance] saveVideoWithVideoPathURL:[NSURL fileURLWithPath:videoPath] albumAssetsGroup:albumAssetsGroup completionBlock:completionBlock];
}
@implementation QMUIAssetsManager {
PHCachingImageManager *_phCachingImageManager;
}
+ (QMUIAssetsManager *)sharedInstance {
static dispatch_once_t onceToken;
static QMUIAssetsManager *instance = nil;
dispatch_once(&onceToken,^{
instance = [[super allocWithZone:NULL] init];
});
return instance;
}
/**
* +allocWithZone 使
*/
+ (id)allocWithZone:(struct _NSZone *)zone {
return [self sharedInstance];
}
- (instancetype)init {
if (self = [super init]) {
}
return self;
}
+ (QMUIAssetAuthorizationStatus)authorizationStatus {
__block QMUIAssetAuthorizationStatus status;
// 访
PHAuthorizationStatus authorizationStatus = [PHPhotoLibrary authorizationStatus];
if (authorizationStatus == PHAuthorizationStatusRestricted || authorizationStatus == PHAuthorizationStatusDenied) {
status = QMUIAssetAuthorizationStatusNotAuthorized;
} else if (authorizationStatus == PHAuthorizationStatusNotDetermined) {
status = QMUIAssetAuthorizationStatusNotDetermined;
} else {
status = QMUIAssetAuthorizationStatusAuthorized;
}
return status;
}
+ (void)requestAuthorization:(void(^)(QMUIAssetAuthorizationStatus status))handler {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus phStatus) {
QMUIAssetAuthorizationStatus status;
if (phStatus == PHAuthorizationStatusRestricted || phStatus == PHAuthorizationStatusDenied) {
status = QMUIAssetAuthorizationStatusNotAuthorized;
} else if (phStatus == PHAuthorizationStatusNotDetermined) {
status = QMUIAssetAuthorizationStatusNotDetermined;
} else {
status = QMUIAssetAuthorizationStatusAuthorized;
}
if (handler) {
handler(status);
}
}];
}
- (void)enumerateAllAlbumsWithAlbumContentType:(QMUIAlbumContentType)contentType showEmptyAlbum:(BOOL)showEmptyAlbum showSmartAlbumIfSupported:(BOOL)showSmartAlbumIfSupported usingBlock:(void (^)(QMUIAssetsGroup *resultAssetsGroup))enumerationBlock {
//
NSArray<PHAssetCollection *> *tempAlbumsArray = [PHPhotoLibrary fetchAllAlbumsWithAlbumContentType:contentType showEmptyAlbum:showEmptyAlbum showSmartAlbum:showSmartAlbumIfSupported];
// PHFetchOptions QMUIAssetsGroup
PHFetchOptions *phFetchOptions = [PHPhotoLibrary createFetchOptionsWithAlbumContentType:contentType];
// QMUIAssetsGroup enumerationBlock
for (NSUInteger i = 0; i < tempAlbumsArray.count; i++) {
PHAssetCollection *phAssetCollection = tempAlbumsArray[i];
QMUIAssetsGroup *assetsGroup = [[QMUIAssetsGroup alloc] initWithPHCollection:phAssetCollection fetchAssetsOptions:phFetchOptions];
if (enumerationBlock) {
enumerationBlock(assetsGroup);
}
}
/**
* enumerationBlock nil
*/
if (enumerationBlock) {
enumerationBlock(nil);
}
}
- (void)enumerateAllAlbumsWithAlbumContentType:(QMUIAlbumContentType)contentType usingBlock:(void (^)(QMUIAssetsGroup *resultAssetsGroup))enumerationBlock {
[self enumerateAllAlbumsWithAlbumContentType:contentType showEmptyAlbum:NO showSmartAlbumIfSupported:YES usingBlock:enumerationBlock];
}
- (void)saveImageWithImageRef:(CGImageRef)imageRef albumAssetsGroup:(QMUIAssetsGroup *)albumAssetsGroup orientation:(UIImageOrientation)orientation completionBlock:(QMUIWriteAssetCompletionBlock)completionBlock {
PHAssetCollection *albumPhAssetCollection = albumAssetsGroup.phAssetCollection;
// PHAssetCollection
[[PHPhotoLibrary sharedPhotoLibrary] addImageToAlbum:imageRef
albumAssetCollection:albumPhAssetCollection
orientation:orientation
completionHandler:^(BOOL success, NSDate *creationDate, NSError *error) {
if (success) {
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:@"creationDate = %@", creationDate];
PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:albumPhAssetCollection options:fetchOptions];
PHAsset *phAsset = fetchResult.lastObject;
QMUIAsset *asset = [[QMUIAsset alloc] initWithPHAsset:phAsset];
completionBlock(asset, error);
} else {
QMUILog(@"QMUIAssetLibrary", @"Get PHAsset of image error: %@", error);
completionBlock(nil, error);
}
}];
}
- (void)saveImageWithImagePathURL:(NSURL *)imagePathURL albumAssetsGroup:(QMUIAssetsGroup *)albumAssetsGroup completionBlock:(QMUIWriteAssetCompletionBlock)completionBlock {
PHAssetCollection *albumPhAssetCollection = albumAssetsGroup.phAssetCollection;
// PHAssetCollection
[[PHPhotoLibrary sharedPhotoLibrary] addImageToAlbum:imagePathURL
albumAssetCollection:albumPhAssetCollection
completionHandler:^(BOOL success, NSDate *creationDate, NSError *error) {
if (success) {
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:@"creationDate = %@", creationDate];
PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:albumPhAssetCollection options:fetchOptions];
PHAsset *phAsset = fetchResult.lastObject;
QMUIAsset *asset = [[QMUIAsset alloc] initWithPHAsset:phAsset];
completionBlock(asset, error);
} else {
QMUILog(@"QMUIAssetLibrary", @"Get PHAsset of image error: %@", error);
completionBlock(nil, error);
}
}];
}
- (void)saveVideoWithVideoPathURL:(NSURL *)videoPathURL albumAssetsGroup:(QMUIAssetsGroup *)albumAssetsGroup completionBlock:(QMUIWriteAssetCompletionBlock)completionBlock {
PHAssetCollection *albumPhAssetCollection = albumAssetsGroup.phAssetCollection;
// PHAssetCollection
[[PHPhotoLibrary sharedPhotoLibrary] addVideoToAlbum:videoPathURL
albumAssetCollection:albumPhAssetCollection
completionHandler:^(BOOL success, NSDate *creationDate, NSError *error) {
if (success) {
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:@"creationDate = %@", creationDate];
PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:albumPhAssetCollection options:fetchOptions];
PHAsset *phAsset = fetchResult.lastObject;
QMUIAsset *asset = [[QMUIAsset alloc] initWithPHAsset:phAsset];
completionBlock(asset, error);
} else {
QMUILog(@"QMUIAssetLibrary", @"Get PHAsset of video Error: %@", error);
completionBlock(nil, error);
}
}];
}
- (PHCachingImageManager *)phCachingImageManager {
if (!_phCachingImageManager) {
_phCachingImageManager = [[PHCachingImageManager alloc] init];
}
return _phCachingImageManager;
}
@end
@implementation PHPhotoLibrary (QMUI)
+ (PHFetchOptions *)createFetchOptionsWithAlbumContentType:(QMUIAlbumContentType)contentType {
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
//
switch (contentType) {
case QMUIAlbumContentTypeOnlyPhoto:
fetchOptions.predicate = [NSPredicate predicateWithFormat:@"mediaType = %i", PHAssetMediaTypeImage];
break;
case QMUIAlbumContentTypeOnlyVideo:
fetchOptions.predicate = [NSPredicate predicateWithFormat:@"mediaType = %i",PHAssetMediaTypeVideo];
break;
case QMUIAlbumContentTypeOnlyAudio:
fetchOptions.predicate = [NSPredicate predicateWithFormat:@"mediaType = %i",PHAssetMediaTypeAudio];
break;
default:
break;
}
return fetchOptions;
}
+ (NSArray<PHAssetCollection *> *)fetchAllAlbumsWithAlbumContentType:(QMUIAlbumContentType)contentType showEmptyAlbum:(BOOL)showEmptyAlbum showSmartAlbum:(BOOL)showSmartAlbum {
NSMutableArray<PHAssetCollection *> *tempAlbumsArray = [[NSMutableArray alloc] init];
// PHFetchOptions QMUIAssetsGroup
PHFetchOptions *fetchOptions = [PHPhotoLibrary createFetchOptionsWithAlbumContentType:contentType];
PHFetchResult *fetchResult;
if (showSmartAlbum) {
//
// PHFetchResult
fetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAny options:nil];
} else {
// PhotoKit
fetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil];
}
//
for (NSInteger i = 0; i < fetchResult.count; i++) {
//
PHCollection *collection = fetchResult[i];
if ([collection isKindOfClass:[PHAssetCollection class]]) {
PHAssetCollection *assetCollection = (PHAssetCollection *)collection;
// fetchResult 0 0
PHFetchResult *currentFetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:fetchOptions];
if (currentFetchResult.count > 0 || showEmptyAlbum) {
//
//
if (assetCollection.assetCollectionSubtype == PHAssetCollectionSubtypeSmartAlbumUserLibrary) {
[tempAlbumsArray insertObject:assetCollection atIndex:0];
} else {
[tempAlbumsArray addObject:assetCollection];
}
}
} else {
NSAssert(NO, @"Fetch collection not PHCollection: %@", collection);
}
}
//
PHFetchResult *topLevelUserCollections = [PHCollectionList fetchTopLevelUserCollectionsWithOptions:nil];
//
for (NSInteger i = 0; i < topLevelUserCollections.count; i++) {
//
PHCollection *collection = topLevelUserCollections[i];
if ([collection isKindOfClass:[PHAssetCollection class]]) {
PHAssetCollection *assetCollection = (PHAssetCollection *)collection;
if (showEmptyAlbum) {
//
[tempAlbumsArray addObject:assetCollection];
} else {
//
PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:fetchOptions];
// fetchResult 0
if (fetchResult.count > 0) {
[tempAlbumsArray addObject:assetCollection];
}
}
}
}
// macOS
PHFetchResult *macCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumSyncedAlbum options:nil];
// macOS
for (NSInteger i = 0; i < macCollections.count; i++) {
//
PHCollection *collection = macCollections[i];
if ([collection isKindOfClass:[PHAssetCollection class]]) {
PHAssetCollection *assetCollection = (PHAssetCollection *)collection;
[tempAlbumsArray addObject:assetCollection];
}
}
NSArray<PHAssetCollection *> *resultAlbumsArray = [tempAlbumsArray copy];
return resultAlbumsArray;
}
+ (PHAsset *)fetchLatestAssetWithAssetCollection:(PHAssetCollection *)assetCollection {
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
// PHAssetCollection
fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:fetchOptions];
// PHAssetCollection
PHAsset *latestAsset = fetchResult.lastObject;
return latestAsset;
}
- (void)addImageToAlbum:(CGImageRef)imageRef albumAssetCollection:(PHAssetCollection *)albumAssetCollection orientation:(UIImageOrientation)orientation completionHandler:(void(^)(BOOL success, NSDate *creationDate, NSError *error))completionHandler {
UIImage *targetImage = [UIImage imageWithCGImage:imageRef scale:ScreenScale orientation:orientation];
[[PHPhotoLibrary sharedPhotoLibrary] addImageToAlbum:targetImage imagePathURL:nil albumAssetCollection:albumAssetCollection completionHandler:completionHandler];
}
- (void)addImageToAlbum:(NSURL *)imagePathURL albumAssetCollection:(PHAssetCollection *)albumAssetCollection completionHandler:(void (^)(BOOL success, NSDate *creationDate, NSError *error))completionHandler {
[[PHPhotoLibrary sharedPhotoLibrary] addImageToAlbum:nil imagePathURL:imagePathURL albumAssetCollection:albumAssetCollection completionHandler:completionHandler];
}
- (void)addImageToAlbum:(UIImage *)image imagePathURL:(NSURL *)imagePathURL albumAssetCollection:(PHAssetCollection *)albumAssetCollection completionHandler:(void(^)(BOOL success, NSDate *creationDate, NSError *error))completionHandler {
__block NSDate *creationDate = nil;
[self performChanges:^{
// PHAsset
PHAssetChangeRequest *assetChangeRequest;
if (image) {
assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
} else if (imagePathURL) {
assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:imagePathURL];
} else {
QMUILog(@"QMUIAssetLibrary", @"Creating asset with empty data");
return;
}
assetChangeRequest.creationDate = [NSDate date];
creationDate = assetChangeRequest.creationDate;
if (albumAssetCollection.assetCollectionType == PHAssetCollectionTypeAlbum) {
// Asset
// PHAssetCollection PHAssetCollection
PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:albumAssetCollection];
/**
* PHAsset PHAssetCollection placeholderForCreatedAsset
* placeholder PHAsset PHAssetCollectionChangeRequest
*/
[assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]];
}
} completionHandler:^(BOOL success, NSError *error) {
if (!success) {
QMUILog(@"QMUIAssetLibrary", @"Creating asset of image error : %@", error);
}
if (completionHandler) {
/**
* performChanges:completionHandler 线 block UI
* block 线
*/
dispatch_async(dispatch_get_main_queue(), ^{
BOOL creatingSuccess = success && creationDate; // nil performChanges performChanges
completionHandler(creatingSuccess, creationDate, error);
});
}
}];
}
- (void)addVideoToAlbum:(NSURL *)videoPathURL albumAssetCollection:(PHAssetCollection *)albumAssetCollection completionHandler:(void(^)(BOOL success, NSDate *creationDate, NSError *error))completionHandler {
__block NSDate *creationDate = nil;
[self performChanges:^{
// PHAsset
PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:videoPathURL];
assetChangeRequest.creationDate = [NSDate date];
creationDate = assetChangeRequest.creationDate;
if (albumAssetCollection.assetCollectionType == PHAssetCollectionTypeAlbum) {
// Asset
// PHAssetCollection PHAssetCollection
PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:albumAssetCollection];
/**
* PHAsset PHAssetCollection placeholderForCreatedAsset
* placeholder PHAsset PHAssetCollectionChangeRequest
*/
[assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]];
}
} completionHandler:^(BOOL success, NSError *error) {
if (!success) {
QMUILog(@"QMUIAssetLibrary", @"Creating asset of video error: %@", error);
}
if (completionHandler) {
/**
* performChanges:completionHandler 线 block UI
* block 线
*/
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(success, creationDate, error);
});
}
}];
}
@end