不知道朋友们有木有做过多图保存到系统的相册这个需求,我在用`UIImageWriteToSavedPhotosAlbum`保存图片时候,在代理回调方`didFinishSavingWithError`中有些图片会出现这样的错误:
原因上面写的很清楚,在同时保存多张图的时候,系统资源有限,来不及处理全部图片,容易出现写入错误。如果每次保存的时候一张保存完再保存另一张,就不会出现这个错误了。
其实管理相册的是`ALAssetsLibrary`这个类,苹果官方对它的描述是这样的:An instance of ALAssetsLibrary provides access to the videos and photos that are under the control of the Photos application. `ALAssetsLibrary`中提供了保存到相册的API:
1 // With a UIImage, the API user can use -[UIImage CGImage] to get a CGImageRef, and cast -[UIImage imageOrientation] to ALAssetOrientation. 2 - (void)writeImageToSavedPhotosAlbum:(CGImageRef)imageRef orientation:(ALAssetOrientation)orientation completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock NS_DEPRECATED_IOS(4_0, 9_0, "Use creationRequestForAssetFromImage: on PHAssetChangeRequest from the Photos framework to create a new asset instead"); 3 4 // The API user will have to specify the orientation key in the metadata dictionary to preserve the orientation of the image 5 - (void)writeImageToSavedPhotosAlbum:(CGImageRef)imageRef metadata:(NSDictionary *)metadata completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock NS_DEPRECATED_IOS(4_1, 9_0, "Use creationRequestForAssetFromImage: on PHAssetChangeRequest from the Photos framework to create a new asset instead"); 6 7 // If there is a conflict between the metadata in the image data and the metadata dictionary, the image data metadata values will be overwritten 8 - (void)writeImageDataToSavedPhotosAlbum:(NSData *)imageData metadata:(NSDictionary *)metadata completionBlock:(ALAssetsLibraryWriteImageCompletionBlock)completionBlock NS_DEPRECATED_IOS(4_1, 9_0, "Use creationRequestForAssetFromImageData: on PHAssetChangeRequest from the Photos framework to create a new asset instead");
后面两个需要提供图片的metadata, 我用的是第一个方法。下面上码~
1. 初始化一个全局的`ALAssetsLibrary`
1 ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
2.封装一个方法,把需要保存的图片放在一个数组中,每次取第一张,调用`writeImageToSavedPhotosAlbum`保存,如果保存成功,则将其移出数组,再保存下一张,如果有错误,我这边是用一个bool变量`isImagesSavedFailed`来记录(我这边需要图片全部保存成功)。
1 typedef void (^completion_t)(id result); 2 3 4 - (void) writeImages:(NSMutableArray*)images 5 completion:(completion_t)completionHandler { 6 if ([images count] == 0) { 7 if (completionHandler) { 8 // Signal completion to the call-site. Use an appropriate result, 9 // instead of @"finished" possibly pass an array of URLs and NSErrors 10 // generated below in "handle URL or error". 11 completionHandler(@"images are all saved."); 12 } 13 return; 14 } 15 UIImage* image = [images firstObject]; 16 [assetsLibrary writeImageToSavedPhotosAlbum:image.CGImage 17 orientation:ALAssetOrientationUp 18 completionBlock:^(NSURL *assetURL, NSError *error){ 19 // Caution: check the execution context - it may be any thread, 20 // possibly use dispatch_async to dispatch to the main thread or 21 // any other queue. 22 // handle URL or error 23 if (error) { 24 NSLog(@"error = %@", [error localizedDescription]); 25 isImagesSavedFailed = true; 26 return; 27 } 28 [images removeObjectAtIndex:0]; 29 // next image: 30 [self writeImages:images completion:completionHandler]; 31 }]; 32 }
3. 调用示例
1 NSMuatableArray *saveImages;//保存到相册的图片 2 [self writeImages:saveImages completion:^(id result) { 3 NSLog(@"Result: %@", result); 4 [hud stopLoading]; 5 if (isImagesSavedFailed) { 6 //handle failed. 7 }else{ 8 //handle success. 9 } 10 }];
======================= 分割线 ===============================
好久木有写博客了,有很多东西木有记录,还是记录下印象深一点。
时间: 2024-09-30 07:04:02