iOS to read the photo library and save pictures or videos to the photo library

  • 2020-06-12 10:41:33
  • OfStack

Read the photo library PhotoLibrary
In iOS, if we only have a need to read a picture or a video (or take a photo/video) once, then we can do it with UIImagePickerController. But there are times when you need to read more than one photo or video at a time from PhotoLibrary, so you need to take a different approach.
Before we start coding we want to recognize a few classes:
ALAssetsLibrary: Representing the entire PhotoLibrary, we can generate an instance object of it, which is equivalent to a handle to the photo library.
ALAssetsGroup: The grouping of the photo library. We can get all the handles of the grouping through the instance of ALAssetsLibrary.
ALAsset: One instance of ALAsset represents one asset, that is, one instance of photo or video, through which we can obtain the corresponding subnail or original image, etc.
One thing to know is blocks, which has been around since iOS 4.0 and is getting more and more useful, but it works. I'm not going to talk about this stuff here, but I'm going to talk about it on my blog.
For the purposes of this article, we read group and each asset asynchronously, but with blocks we can do it in 1 function. So blocks is really convenient.
Let's go straight to the code:


ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc]init];// To generate the photolibrary An instance of a handle    
NSMutableArray *mediaArray = [[NSMutableArray alloc]init];// store media An array of    
    [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {// Get all the group   
        [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {// from group inside    
            NSString* assetType = [result valueForProperty:ALAssetPropertyType];   
            if ([assetType isEqualToString:ALAssetTypePhoto]) {   
                NSLog(@"Photo");   
            }else if([assetType isEqualToString:ALAssetTypeVideo]){   
                NSLog(@"Video");   
            }else if([assetType isEqualToString:ALAssetTypeUnknown]){   
                NSLog(@"Unknow AssetType");   
            }   
               
            NSDictionary *assetUrls = [result valueForProperty:ALAssetPropertyURLs];   
            NSUInteger assetCounter = 0;   
            for (NSString *assetURLKey in assetUrls) {   
                NSLog(@"Asset URL %lu = %@",(unsigned long)assetCounter,[assetUrls objectForKey:assetURLKey]);   
            }   
               
            NSLog(@"Representation Size = %lld",[[result defaultRepresentation]size]);   
        }];   
    } failureBlock:^(NSError *error) {   
        NSLog(@"Enumerate the asset groups failed.");   
    }];  

Save pictures or videos to PhotoLibrary
When the file is then, then the path to the temporary file is saved to photo library.
Let's look directly at the corresponding API:


// These methods can be used to add photos or videos to the saved photos album. 
 
// With a UIImage, the API user can use -[UIImage CGImage] to get a CGImageRef, and cast -[UIImage imageOrientation] to ALAssetOrientation. 
- (void)writeImageToSavedPhotosAlbum:(CGImageRef)imageRef orientation:(ALAssetOrientation)orientation completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock; 
 
// The API user will have to specify the orientation key in the metadata dictionary to preserve the orientation of the image 
- (void)writeImageToSavedPhotosAlbum:(CGImageRef)imageRef metadata:(NSDictionary *)metadata completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_1); 
 
// If there is a conflict between the metadata in the image data and the metadata dictionary, the image data metadata values will be overwritten 
- (void)writeImageDataToSavedPhotosAlbum:(NSData *)imageData metadata:(NSDictionary *)metadata completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_1); 
 
- (void)writeVideoAtPathToSavedPhotosAlbum:(NSURL *)videoPathURL completionBlock:(ALAssetsLibraryWriteVideoCompletionBlock)completionBlock; 

First three are save image, through the parameters we can find that first we go in the direction of the transfer, the second by the incoming image metadata retain image metadata, the first two are the images into CGImageRef save again, the third is the incoming NSData so may keep image complete information, as well as metadata handed in, if image bringing information conflict with metadata metadata will cover itself with metadata images.
The last one is API to store the video. You can see that the parameter is 1 NSURL. This one only needs to wear 1 local temporary file file URL.
Select the appropriate API to store images according to your needs. For example, if we get an instance of UIImage, it is convenient for us to use the first or second one. If we read image data from a local temporary file, it is convenient for us to use the third one directly.
Here's a simple piece of code:

- (void)saveImage:(UIImage*)image{ 
    ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc]init]; 
    [assetsLibrary writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)image.imageOrientation completionBlock:^(NSURL *assetURL, NSError *error) { 
        if (error) { 
            NSLog(@"Save image fail : %@",error); 
        }else{ 
            NSLog(@"Save image succeed."); 
        } 
    }]; 


To save video, you need to first write video to a local file, then get the path to a local temporary file, and then call API above to write photo library.
As for writing temporary files, I have written an article about reading and writing files before. You can check it out.
I have attached one video from the engineering resource library to demo from photo, so that you can import video into the simulator for testing sometime.
The main codes are as follows:

- (void)save:(NSString*)urlString{ 
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 
    [library writeVideoAtPathToSavedPhotosAlbum:[NSURL fileURLWithPath:urlString] 
                                completionBlock:^(NSURL *assetURL, NSError *error) { 
                                    if (error) { 
                                        NSLog(@"Save video fail:%@",error); 
                                    } else { 
                                        NSLog(@"Save video succeed."); 
                                    } 
                                }]; 


Related articles: