文档章节

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

琳小兮
 琳小兮
发布于 2015/09/01 17:31
字数 958
阅读 238
收藏 1
iOS

在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];
}


© 著作权归作者所有

琳小兮
粉丝 30
博文 61
码字总数 28637
作品 0
襄阳
程序员
私信 提问
加载中

评论(1)

derchance
derchance
感谢分享,完美解决问题
iOS版本兼容-8.4.1-tableViewCell侧滑崩溃闪退的问题

前言 昨天加班,本来顺顺利利的,后来测试拿了一个6P来测,装的是8.4.1的系统,我心说真牛,这么老的系统还留着,测试说,就怕有些用户不更新,就喜欢这个版本.本来也没有什么大不了,可没想到测出来的...

五蕴盛
2017/12/25
0
0
Lotus Notes打开后闪退的解决方法

Lotus Notes打开后闪退的解决方法 éŠŹć–‡ĺťşçš„ĺšĺŽ˘2015-06-245 阅读 Lotus 前些天我在 Lotus Notes 处于打开状态的情况下强行关机,于是以后只要一打开这软件,这货就自...

éŠŹć–‡ĺťşçš„ĺšĺŽ˘
2015/06/24
0
0
iOS 启动连续闪退保护方案

版权声明:本文由刘笑江原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/79 来源:腾云阁 https://www.qcloud.com/community 一.引言 “如果某个实体表现...

偶素浅小浅
2016/11/02
2
0
AVD,SDK manager 闪退

SDK manager闪退: 直接找到tool 中的android.bat运行即可 AVD manager闪退解决方法: 修改 android.bat文件,指定java.exe所在位置。 找到 android.bat文件(例如C:Program Files (x86)Andr...

程序媛媛51
2016/10/13
0
0
iOS应用崩溃日志分析

iOS应用崩溃日志分析 为确保你的应用正确无误,在将其提交到应用商店之前,你必定进行了大量的测试工作。它在你的设备上也运行得很好,但是,上了应用商店后,还是有用户抱怨会闪退 ! 如果你...

法斗斗
2015/10/08
58
0

没有更多内容

加载失败,请刷新页面

加载更多

lombok的一个踩坑记录

lombok的类如下所示: package com.divx.service.model.task;import com.divx.service.model.BaseTypeMedia;import lombok.Data;/** * @author wuzhilang * @Title: QuestionResult ......

无知的小狼
39分钟前
2
0
如何使用markdown

我没有导入相应的包 这个用的还是有些问题 而且显示的时候格式问题还没解决 <div class="blog_editor" style="margin: 0 auto;width:60%;height:1000px;background-color: white;"> <div s......

南桥北木
42分钟前
4
0
纯手写SpringBoot框架之注解方式启动SpringMVC容器

使用Java语言创建Tomcat容器,并且通过Tomcat执行Servlet,接下来,将会使用Java语言在SpringBoot创建内置Tomcat,使用注解方式启动SpringMVC容器。 代码实现。 1.pom.xml文件,需要依赖的jar...

Java老王
44分钟前
2
0
Presto查询引擎简单分析

Hive查询流程分析 各个组件的作用 UI(user interface)(用户接口):提交数据操作的窗口 Driver(引擎):负责接收数据操作,实现了会话句柄,并提供基于JDBC / ODBC的execute和fetch API Metas...

MobService
45分钟前
1
0
《软件架构的10个常见模式》,看完真心觉得不错

作者:半吊子全栈工匠原文链接:https://blog.csdn.net/wireless_com/article/details/89008061 企业规模的软件系统该如何设计呢?在开始写代码之前,我们需要选择一个合适的架构,这个架构...

Java干货分享
57分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部