I am developing an iPhone photo application, so i need to create a separate album with a name \"My Album\" in camera roll and i need to save my UIImageView image with custom
/// Save images or videos(保存图片或视频)(kUTTypeImage, kUTTypeMovie)
/// Add to album if specified album name, and create album if needed
/// @params mediaArray UIImage, fileURL for a image or video
+ (void)_saveMediaArray:(NSArray *)mediaArray
options:(LAImageSaverOptions *)options
completion:(void (^)(NSError * _Nullable err))completion
{
NSInteger __block count = 0;
[PHPhotoLibrary.sharedPhotoLibrary performChanges:^{
// Create album if needed
PHAssetCollectionChangeRequest *assetCollectionChangeRequest = nil;
NSMutableArray *assetChangeRequestPlaceholders = nil;
if (options.targetAlbumName.length > 0) {
assetChangeRequestPlaceholders = [NSMutableArray arrayWithCapacity:mediaArray.count];
PHFetchOptions *fetchOptions = PHFetchOptions.new;
//fetchOptions.includeAssetSourceTypes = PHAssetSourceTypeUserLibrary;
fetchOptions.predicate = [NSPredicate predicateWithFormat:@"localizedTitle = %@", options.targetAlbumName]; // 不能用 block 形式的 predicate
PHAssetCollection * assetCollection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:fetchOptions].firstObject;
if (nil == assetCollection) {
assetCollectionChangeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:options.targetAlbumName];
} else {
assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
}
}
// Save images
for (id item in mediaArray) {
PHAssetChangeRequest *assetChangeRequest = nil;
// image object
if ([item isKindOfClass:UIImage.class]) {
UIImage *image = (UIImage *)item;
assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
[assetChangeRequestPlaceholders addObject:assetChangeRequest.placeholderForCreatedAsset];
++count;
continue;
}
// file url for image or movie
NSURL *fileURL = (NSURL *)item;
if ([item isKindOfClass:NSURL.class] && fileURL.isFileURL) {
NSString *extension = fileURL.pathExtension;
if (extension.length == 0) {
NSLog(@"illegal fileURL(no path extension): %@", fileURL);
continue; // illegal file url
}
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)extension, NULL);
BOOL isImage = false;
BOOL isVideo = false;
if (nil != uti && CFStringGetLength(uti) > 0) {
isImage = UTTypeConformsTo(uti, kUTTypeImage);
isVideo = UTTypeConformsTo(uti, kUTTypeMovie); // kUTTypeVideo, kUTTypeAudiovisualContent
}
if (isImage) {
assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:fileURL];
[assetChangeRequestPlaceholders addObject:assetChangeRequest.placeholderForCreatedAsset];
++count;
} if (isVideo) {
assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:fileURL];
[assetChangeRequestPlaceholders addObject:assetChangeRequest.placeholderForCreatedAsset];
++count;
} else {
NSLog(@"illegal fileURL(neither image nor movie): %@", fileURL);
continue; // illegal file url
}
}
}
// add to album if needed
[assetCollectionChangeRequest addAssets:assetChangeRequestPlaceholders];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
// not in main thread
dispatch_async(dispatch_get_main_queue(), ^{
completion(error);
});
}];
}
By the way, you can do more about LAImageSaverOptions
@interface LAImageSaverOptions : NSObject
/// to show alert controller on the hostVC
@property(nonatomic, weak, null_resettable) UIViewController *hostVC;
/// total progress
@property (nonatomic, strong, null_resettable) NSProgress *progress;
// album name for saving images
@property (nonatomic, copy, nullable) NSString *targetAlbumName;
@end