不知道朋友們有木有作過多圖保存到系統的相冊這個需求,我在用`UIImageWriteToSavedPhotosAlbum`保存圖片時候,在代理回調方`didFinishSavingWithError`中有些圖片會出現這樣的錯誤:ios
緣由上面寫的很清楚,在同時保存多張圖的時候,系統資源有限,來不及處理所有圖片,容易出現寫入錯誤。若是每次保存的時候一張保存完再保存另外一張,就不會出現這個錯誤了。數組
其實管理相冊的是`ALAssetsLibrary`這個類,蘋果官方對它的描述是這樣的:An instance of ALAssetsLibrary provides access to the videos and photos that are under the control of the Photos application. `ALAssetsLibrary`中提供了保存到相冊的API:app
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, 我用的是第一個方法。下面上碼~async
1. 初始化一個全局的`ALAssetsLibrary`ide
1 ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init]; spa
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 }];
======================= 分割線 ===============================blog
很久木有寫博客了,有不少東西木有記錄,仍是記錄下印象深一點。圖片