iOS8使用ALAssetsLibrar创建单独文件夹方法以及删除文件夹闪退的bug

在ios8以下的系统创建新相册,然后在相册中手动删除了这个"琳小兮"相册,再使用下面的代码重新创建"琳小兮"相册是没有问题的:

[assetsLibrary addAssetsGroupAlbumWithName:@"琳小兮"
     resultBlock:^(ALAssetsGroup *group)
                 {
                     [groups addObject:group];
                 }
             failureBlock:nil];

ios8+ 包含ios8系统,若文件夹已被手动删除,再创建同名文件夹的时候用上面的代码则会崩溃,需要额外添加Photos.framework框架,并导入头文件#import <Photos/Photos.h>,主要修改的代码部分是把上面那段代码做如下修改:

[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^
                 {
                     [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"琳小兮"];
                 } completionHandler:^(BOOL success, NSError *error)
                 {
                     if (!success) {
                         NSLog(@"---error:%@",error.userInfo);
                     }
                 }];


下面是完整的demo,结合了网上的实例写的,给大家做一个参考:


1.添加AssetsLibrary.framework 和 Photos.framework框架


2.导入头文件


#import <AssetsLibrary/AssetsLibrary.h>


#import <Photos/Photos.h>


3.代码如下:

@interface ViewController ()<UIActionSheetDelegate>
{
    NSMutableArray *imageArray;      //存图片的数组
    int selectedImageIndex;                 //当前长按的下标
}
@end
@implementation ViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    imageArray = [[NSMutableArray alloc] initWithObjects:[UIImage imageNamed:@"1.png"],[UIImage imageNamed:@"2.png"],[UIImage imageNamed:@"3.png"],[UIImage imageNamed:@"4.png"], nil];
    
    [self initImageView];
}
#pragma mark - 创建UI
-(void)initImageView
{
    for (int i = 0; i < imageArray.count; i ++) {
        UIImageView *  _imageV = [[UIImageView alloc] initWithFrame:CGRectMake(100, 50+110*i, 80, 80)];
        _imageV.image = imageArray[i];
        _imageV.userInteractionEnabled = YES;
        _imageV.tag = 100+i;
        [_imageV addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]];
        [self.view addSubview:_imageV];
    }
}
#pragma mark - 在手机相册中创建新相册
- (void)createAlbumInPhoneAlbum:(UIImage *)senderImage
{
    ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
    NSMutableArray *groups=[[NSMutableArray alloc]init];
    ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOL *stop)
    {
        if (group)
        {
            [groups addObject:group];
        }
        else
        {
            BOOL haveHDRGroup = NO;
            
            for (ALAssetsGroup *gp in groups)
            {
                NSString *name =[gp valueForProperty:ALAssetsGroupPropertyName];
                
                if ([name isEqualToString:@"琳小兮"])
                {
                    haveHDRGroup = YES;
                }
            }
            
            if (!haveHDRGroup)
            {
                //添加一个新的相册
                //此方法在ios8.0系统上,之前用代码创建的相册,手动删除它,再用这个库去创建刚被删除的相册,这个时候方法回调是不会跑fail模块的,它走的是正常流程,但是带回来的group却是nil
//                [assetsLibrary addAssetsGroupAlbumWithName:@"琳小兮"
//                                               resultBlock:^(ALAssetsGroup *group)
//                 {
//                     NSLog(@"--------%@",group);
//                     [groups addObject:group];
//                 }
//                                              failureBlock:nil];
                //为了解决iOS8.0以上系统下无法通过代码创建被删除过的同名相册
                [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^
                 {
                     [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"琳小兮"];
                     
                 } completionHandler:^(BOOL success, NSError *error)
                 {
                     if (!success) {
                         NSLog(@"---error:%@",error.userInfo);
                     }
                 }];
                
                haveHDRGroup = YES;
            }
        }
        
    };
    
    [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:listGroupBlock failureBlock:nil];
    
    [self saveToAlbumWithMetadata:nil imageData:UIImagePNGRepresentation(senderImage) customAlbumName:@"琳小兮" completionBlock:^
     {
         //这里可以创建添加成功的方法
         [self showAlert:@"图片保存成功!"];
     }
                     failureBlock:^(NSError *error)
     {
         //添加失败一般是由用户不允许应用访问相册造成的,这边可以取出这种情况加以判断一下
         if([error.localizedDescription rangeOfString:@"User denied access"].location != NSNotFound ||[error.localizedDescription rangeOfString:@"用户拒绝访问"].location!=NSNotFound){
             [self showAlert:error.localizedFailureReason];
         }
     }];
}
#pragma mark 保存图片
- (void)saveToAlbumWithMetadata:(NSDictionary *)metadata
                      imageData:(NSData *)imageData
                customAlbumName:(NSString *)customAlbumName
                completionBlock:(void (^)(void))completionBlock
                   failureBlock:(void (^)(NSError *error))failureBlock
{
    
    ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
    void (^AddAsset)(ALAssetsLibrary *, NSURL *) = ^(ALAssetsLibrary *assetsLibrary, NSURL *assetURL) {
        [assetsLibrary assetForURL:assetURL resultBlock:^(ALAsset *asset) {
            [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
                
                if ([[group valueForProperty:ALAssetsGroupPropertyName] isEqualToString:customAlbumName]) {
                    [group addAsset:asset];
                    if (completionBlock) {
                        completionBlock();
                    }
                }
            } failureBlock:^(NSError *error) {
                if (failureBlock) {
                    failureBlock(error);
                }
            }];
        } failureBlock:^(NSError *error) {
            if (failureBlock) {
                failureBlock(error);
            }
        }];
    };
    [assetsLibrary writeImageDataToSavedPhotosAlbum:imageData metadata:metadata completionBlock:^(NSURL *assetURL, NSError *error) {
        if (customAlbumName) {
            [assetsLibrary addAssetsGroupAlbumWithName:customAlbumName resultBlock:^(ALAssetsGroup *group) {
                if (group) {
                    [assetsLibrary assetForURL:assetURL resultBlock:^(ALAsset *asset) {
                        [group addAsset:asset];
                        if (completionBlock) {
                            completionBlock();
                        }
                    } failureBlock:^(NSError *error) {
                        if (failureBlock) {
                            failureBlock(error);
                        }
                    }];
                } else {
                    AddAsset(assetsLibrary, assetURL);
                }
            } failureBlock:^(NSError *error) {
                AddAsset(assetsLibrary, assetURL);
            }];
        } else {
            if (completionBlock) {
                completionBlock();
            }
        }
    }];
}
#pragma mark - 长按手势
-(void)longPress:(UILongPressGestureRecognizer *)recognizer
{
    //当长按手势结束的时候触发
    if(recognizer.state == UIGestureRecognizerStateEnded)
    {
        UILongPressGestureRecognizer *tempLP = (UILongPressGestureRecognizer *)recognizer;
        //获得该手势被添加到哪个View
        UIImageView *imageV = (UIImageView *)tempLP.view;
        selectedImageIndex = (int)imageV.tag-100;
        
        NSLog(@"当前选中的是第%d张图片",selectedImageIndex);
        
        UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:nil
                                                          delegate:self
                                                 cancelButtonTitle:@"取消"
                                            destructiveButtonTitle:nil
                                                 otherButtonTitles:@"保存到手机",nil];
        menu.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
        [menu showInView:self.view];
    }
}
#pragma mark UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    switch (buttonIndex) {
        case 0:
        {
            [self createAlbumInPhoneAlbum:imageArray[selectedImageIndex]];
        }
            break;
        default:
            break;
    }
}
#pragma mark encapsulationAlert
-(void)showAlert:(NSString *)altString
{
      UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"提示" message:altString delegate:nil cancelButtonTitle:@"确定" otherButtonTitles: nil];
    [alertView show];
}