iPhone - How to create a custom album and give custom names to photos in camera roll programmatically?

后端 未结 6 1355
孤城傲影
孤城傲影 2020-12-08 01:10

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

6条回答
  •  無奈伤痛
    2020-12-08 02:07

    /// 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
    

提交回复
热议问题