最近需要用到一个功能,将一张图片保存到自定义的一个相册中去,这个方法很常用,但是写起来代码有点冗杂,所以决定封装成一个工具类,方便以后的使用。
-
苹果在iOS9 以后推荐使用此方法。
-
但是本方法支持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
-
主要的几个方法
- 授权
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
}];
- 获取照片库这个单例 以及操作它的两个方法
[PHPhotoLibrary sharedPhotoLibrary]
//操作
[[PHPhotoLibrary sharedPhotoLibrary]performChanges。。。。
[[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait。。。
- 相册创建与获取
//从已经存在的相簿中查找应用对应的相册
PHFetchResult <PHAssetCollection *>*assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
//创建相册
[PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle
- 相片(资源)的保存
//保存到相机胶卷
[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
网友评论