在App中很常常遇到的就是用戶點擊某張圖片後將圖片保存到本地,下面介紹下iOS中保存圖片的一些東西網絡
1 - (IBAction)save:(id)sender { 2 // 存儲圖片到"相機膠捲" 3 UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 4 } 5 6 // 成功保存圖片到相冊中, 必須調用此方法, 不然會報參數越界錯誤 7 - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{ 8 9 }
1 - (void)viewDidLoad { 2 [super viewDidLoad]; 3 4 UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic25.nipic.com/20121209/9252150_194258033000_2.jpg"]]]; 5 [self saveImage:image]; 6 } 7 - (void)saveImage:(UIImage*)image { 8 ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 9 10 [library writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)image.imageOrientation completionBlock:^(NSURL *assetURL, NSError *error) { 11 if (error) { 12 NSLog(@"Save image fail:%@",error); 13 }else{ 14 NSLog(@"Save image succeed."); 15 } 16 }]; 17 }
Photos.framework框架很是強大,不止圖片,自拍、全景、iOS9中新增的Live Photo、甚至視頻等等,框架都有詳細的劃分和功能設置閉包
在這裏我要實現的是第一種方法實現不了的功能,那就是建一個屬於這個App的相簿,這個功能確實會常常遇到,代碼以下,有詳細註釋:app
1 - (void)saveImage { 2 //保存圖片 3 __block NSString *assetId = nil; 4 // 1. 存儲圖片到"相機膠捲" 5 [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ 6 // 新建一個PHAssetCreationRequest對象 7 // 返回PHAsset(圖片)的字符串標識 8 assetId = [PHAssetCreationRequest creationRequestForAssetFromImage:self.imageView.image].placeholderForCreatedAsset.localIdentifier; 9 } completionHandler:^(BOOL success, NSError * _Nullable error) { 10 // 2. 得到相冊對象 11 PHAssetCollection *collection = [self getCollection]; 12 // 3. 將「相機膠捲」中的圖片添加到新的相冊 13 [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ 14 PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection]; 15 NSLog(@"%@", [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil]); 16 // 根據惟一標示得到相片對象 17 PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil].firstObject; 18 // 添加圖片到相冊中 19 [request addAssets:@[asset]]; 20 } completionHandler:^(BOOL success, NSError * _Nullable error) { 21 NSLog(@"成功保存到相簿:%@", collection.localizedTitle); 22 }]; 23 }]; 24 } 25 26 - (PHAssetCollection *)getCollection { 27 // 先得到以前建立過的相冊 28 PHFetchResult<PHAssetCollection *> *collectionResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; 29 for (PHAssetCollection *collection in collectionResult) { 30 if ([collection.localizedTitle isEqualToString:@"知乎日報"]) { 31 return collection; 32 } 33 } 34 35 // 若是相冊不存在,就建立新的相冊(文件夾) 36 __block NSString *collectionId = nil; // __block修改block外部的變量的值 37 // 這個方法會在相冊建立完畢後纔會返回 38 [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{ 39 // 新建一個PHAssertCollectionChangeRequest對象, 用來建立一個新的相冊 40 collectionId = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"知乎日報"].placeholderForCreatedAssetCollection.localIdentifier; 41 } error:nil]; 42 43 return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[collectionId] options:nil].firstObject; 44 }
最後的話框架
Photos.framework框架確實很是強大,但在閱讀Apple官方文檔後,在使用時真的很是麻煩,在我看來,這個框架相似於Core Data,你的每一次操做都必須創建本身的Request,並在內存中建一箇中間相簿進行緩衝,而且全部操做,系統都是在後臺完成。fetch
另外要注意的一點是:completionHandler:返回的閉包中不要進行前臺視圖的刷新操做!!!這是Apple文檔中明確提到的。spa