美文网首页程序员iOS Developer
iOS将图片保存到自定义相册方法封装

iOS将图片保存到自定义相册方法封装

作者: 指尖书法 | 来源:发表于2017-05-08 13:31 被阅读533次

最近需要用到一个功能,将一张图片保存到自定义的一个相册中去,这个方法很常用,但是写起来代码有点冗杂,所以决定封装成一个工具类,方便以后的使用。

  • 苹果在iOS9 以后推荐使用此方法。

  • 但是本方法支持iOS8及以上(调用)

真的是iOS8及以上,不骗你
  • 使用PHPhoto.h 框架

跟着我凌波微步四步走——Let's go!!


1. 判断相册目前的权限

 //判断授权状态
    PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
    if (status == PHAuthorizationStatusAuthorized) {
        //已授权
        [self saveImageWithImage:image albumName:albumName];
    }else if(status == PHAuthorizationStatusDenied) {
        //拒绝
        [SVProgressHUD showErrorWithStatus:@"请打开访问相册的权限"];
    }else if (status == PHAuthorizationStatusNotDetermined) {
        //未决定
        // 弹框请求用户授权
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
            if (status == PHAuthorizationStatusAuthorized) { // 用户点击了好
                [self saveImageWithImage:image albumName:albumName];
            }
        }];
    }else if (status == PHAuthorizationStatusRestricted) {
        //家长控制模式限制
        [SVProgressHUD showErrorWithStatus:@"因为系统原因, 无法访问相册"];
    }

2. 将图片保存到相机胶卷中

注意理清这三者的关系,帮助我们更好的理解这个框架中繁琐的代码

  • PHotoLibrary 整个照片库(里面会有很多相册)
  • PHAssetCollection : 一个相簿 (也可以说是一个相册)
  • PHAsset : 一个资源,一个图片
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        
        // 1.保存图片到相机胶卷中
        assetLocalIdentifier = [PHAssetChangeRequest creationRequestForAssetFromImage:image].placeholderForCreatedAsset.localIdentifier;
        
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
        
        if (success == NO) {
            [self showError:@"保存照片失败"];
            return ;
        }

3. 创建一个相册

两步走:

  • 寻找手机中是否已存在相同名字的相册
  • 有就返回,开始保存图片到里面,没有就创建一个。
//从已经存在的相簿中查找应用对应的相册
    PHFetchResult <PHAssetCollection *>*assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    for (PHAssetCollection *collection in assetCollections) {
        if ([collection.localizedTitle isEqualToString:albumName]) {
            return collection;
        }
    }
    // 没找到,就创建新的相簿
    NSError *error;
    __block NSString *assetCollectionLocalIdentifier = nil;
    //这里用wait请求,保证创建成功相册后才保存进去
    [[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
        assetCollectionLocalIdentifier = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:albumName].placeholderForCreatedAssetCollection.localIdentifier;
        
    } error:&error];
    
    if(error) return nil;
    
    return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[assetCollectionLocalIdentifier] options:nil].lastObject;

4. 保存到指定的相册中

//创建成功,就把图片保存到相册中
        [[PHPhotoLibrary sharedPhotoLibrary]performChanges:^{
            
            //添加相机胶卷中的图片到相簿中去
            PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetLocalIdentifier] options:nil].lastObject;
            //添加图片到相册中的请求
            PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:creatAssetCollction];
            [request addAssets:@[asset]];
            
        } completionHandler:^(BOOL success, NSError * _Nullable error) {
            
            if (success == NO) {
                [self showError:@"保存图片失败!"];
            }else {
                [self showSuccess:@"保存图片成功"];
            }
        }];

总结

  • 注意整体逻辑

  • 主要的对象主体
    PHPhotoLibrary
    PHAssetCollection
    PHAsset

  • 主要的几个方法

  1. 授权
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {

        }];
  1. 获取照片库这个单例 以及操作它的两个方法
[PHPhotoLibrary sharedPhotoLibrary]
//操作
[[PHPhotoLibrary sharedPhotoLibrary]performChanges。。。。
[[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait。。。
  1. 相册创建与获取
//从已经存在的相簿中查找应用对应的相册
    PHFetchResult <PHAssetCollection *>*assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
//创建相册
[PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle
  1. 相片(资源)的保存
//保存到相机胶卷
[PHAssetChangeRequest creationRequestForAssetFromImage:image]
//添加图片到相册中的请求
            PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:creatAssetCollction];
            [request addAssets:@[asset]];

最后献上完整代码~

.m 文件(可以直接复制过去用)

#import "NSObject+XHHSaveImageToAlbum.h"
#import <Photos/Photos.h>
@implementation NSObject (XHHSaveImageToAlbum)

//保存图片按钮的点击
-(void)saveImageToAlbumWithImag:(UIImage *)image albumName:(NSString *)albumName {
    
    //判断授权状态
    PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
    if (status == PHAuthorizationStatusAuthorized) {
        //已授权
        [self saveImageWithImage:image albumName:albumName];
    }else if(status == PHAuthorizationStatusDenied) {
        //拒绝
        [SVProgressHUD showErrorWithStatus:@"请打开访问相册的权限"];
    }else if (status == PHAuthorizationStatusNotDetermined) {
        //未决定
        // 弹框请求用户授权
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
            if (status == PHAuthorizationStatusAuthorized) { // 用户点击了好
                [self saveImageWithImage:image albumName:albumName];
            }
        }];
    }else if (status == PHAuthorizationStatusRestricted) {
        //家长控制模式限制
        [SVProgressHUD showErrorWithStatus:@"因为系统原因, 无法访问相册"];
    }
}

//真正保存图片
- (void)saveImageWithImage:(UIImage *)image albumName:(NSString *)albumName{
    // PHAsset : 一个资源,一个图片
    // PHAssetCollection : 一个相簿 (也可以说是一个相册)
    // PHotoLibrary 整个照片库(里面会有很多相册)
    
    __block NSString *assetLocalIdentifier = nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        
        // 1.保存图片到相机胶卷中
        assetLocalIdentifier = [PHAssetChangeRequest creationRequestForAssetFromImage:image].placeholderForCreatedAsset.localIdentifier;
        
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
        
        if (success == NO) {
            [self showError:@"保存照片失败"];
            return ;
        }
        
        // 2. 获得相册
        PHAssetCollection *creatAssetCollction = [self creatPHAssetCollectionWithAlbumName:albumName];
        if (creatAssetCollction == nil) {
            [self showError:@"创建相册失败"];
            return;
        }
        
        //创建成功,就把图片保存到相册中
        [[PHPhotoLibrary sharedPhotoLibrary]performChanges:^{
            
            //添加相机胶卷中的图片到相簿中去
            PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetLocalIdentifier] options:nil].lastObject;
            //添加图片到相册中的请求
            PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:creatAssetCollction];
            [request addAssets:@[asset]];
            
        } completionHandler:^(BOOL success, NSError * _Nullable error) {
            
            if (success == NO) {
                [self showError:@"保存图片失败!"];
            }else {
                [self showSuccess:@"保存图片成功"];
            }
        }];
        
    }];
}

- (void)showSuccess:(NSString *)text
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [SVProgressHUD showSuccessWithStatus:text];
    });
}

- (void)showError:(NSString *)text
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [SVProgressHUD showErrorWithStatus:text];
    });
}

-(PHAssetCollection *)creatPHAssetCollectionWithAlbumName:(NSString *)albumName{
    
    //从已经存在的相簿中查找应用对应的相册
    PHFetchResult <PHAssetCollection *>*assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    for (PHAssetCollection *collection in assetCollections) {
        if ([collection.localizedTitle isEqualToString:albumName]) {
            return collection;
        }
    }
    // 没找到,就创建新的相簿
    NSError *error;
    __block NSString *assetCollectionLocalIdentifier = nil;
    //这里用wait请求,保证创建成功相册后才保存进去
    [[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
        assetCollectionLocalIdentifier = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:albumName].placeholderForCreatedAssetCollection.localIdentifier;
        
    } error:&error];
    
    if(error) return nil;
    
    return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[assetCollectionLocalIdentifier] options:nil].lastObject;
}

@end

相关文章

网友评论

    本文标题:iOS将图片保存到自定义相册方法封装

    本文链接:https://www.haomeiwen.com/subject/vgumtxtx.html