保存到相册ios方法有很多 但是随着技术的更新而且现在已经是iOS11了所以我只介绍最新的方法(其中授权代码是iOS8出来的 保存相册的/创建自定义的代码是ios9出来的)
对于相册我们应该分清楚几个事情:
PHAsset :单个图片
PHAssetCollection :一个相簿
保存到自定义相册的步骤
判断授权状态
将图片保存到相簿
创建自定义的相薄
将相片保存到自定义的相薄
我们开始的代码书写并且我将会介绍每一段代码的意思
- 开始请求授权
// 请求授权
[PHPhotoLibraryrequestAuthorization:^(PHAuthorizationStatusstatus) {
// 先判断是否可以授权
switch(status) {
casePHAuthorizationStatusNotDetermined:
{
XMGLOG(@"用户还没有开始做出选择");
}
break;
casePHAuthorizationStatusAuthorized:
{
XMGLOG(@"用户授权了");
// 我们所有的操作都在这个方法里
[selfsaveImage];
}
break;
default:
{
// 这里的状态不在描述,文档里有4种状态,写的很明白
XMGLOG(@"用户不允许");
}
break;
}
}];
- 在这里开始进行保存图片和创建相簿的操作
1)将图片保存到系统的相簿(如果你只保存到系统的相簿不创建自定义的相簿后面的步骤可以不用看了)
/**
*
* 保存图片到自定义的相册
*/
- (void)saveImage {
// 根据苹果的官方文档,所有的改变/创建/删除等的操作都要[PHPhotoLibrary sharedPhotoLibrary] performChanges:执行或者 -[PHPhotoLibrary performChangesAndWait:] block里进行操作
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// 1.将图片保存到相簿
[PHAssetCreationRequest creationRequestForAssetFromImage:self.downloadImage];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
}];
}
2)创建自定义的相簿(都是在saveimage方法里 后面不在复述)
// 其中collectionTitle 是相簿的名字 我写的是全局的变量 在我的项目中我写的是
static NSString *collectionTitle = @"百思不得姐的相簿";这个方法单单是创建相簿 注意:需要在第一步操作成功之后才能执行这段代码
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:collectionTitle];
}
} completionHandler:^(BOOL success, NSError * _Nullable error) {
}];
2.1)第一步和第二部合起来的操作是
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// 1.将图片保存到相簿
[PHAssetCreationRequest creationRequestForAssetFromImage:self.downloadImage];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
// 2.创建自定义的相薄
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:collectionTitle];
}
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
}
}];
}
}];
3)将图片保存到我们创建的自定义的相簿(说明:按照我们的理解 collection可以添加asset但是看了头文件他偏偏没有,当时我真的郁闷了后来继续查头文件看到一个PHAssetCollectionChangeRequest有一个添加/删除/插入等等的方法 所以我的思路就是:创建PHAssetCollectionChangeRequest(通过collection)然后添加asset,实际上并没有我们想的这么简单 我会在下面说的很清楚 )
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// 3. 将相片保存到自定义的相薄
PHAssetCollection *collection = nil;
PHAsset *asset = nil;
// 我刚才说了PHAssetCollectionChangeRequest 可以添加asset PHAssetCollectionChangeRequest的创建需要collection
PHAssetCollectionChangeRequest *requestCollection = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
// 添加进自定义的相册
[requestCollection addAssets:@[asset]];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
XMGLOG(@"保存相册成功了 哈哈哈");
}
}];
3.1)我们现在的问题是怎样拿到我们创建的相簿(collection)和对应图片的asset
// 我们用这个方法拿到我们创建的自定义的相簿
collection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[collectionIdentifier] options:nil].lastObject;
3.2)我们现在的问题又来了:怎样拿到collectionIdentifier 下面的代码是怎么样拿到collectionIdentifier
// 其实我写的第二步的时候我只写了创建的代码 实际上他也可以获得localIdentifier,因此我们推倒出asset 也可以用同样的思路获得
collectionIdentifier = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:collectionTitle].placeholderForCreatedAssetCollection.localIdentifier;
3.3)下面是第三部完成的代码
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// 3. 将相片保存到自定义的相薄
PHAssetCollection *collection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[collectionIdentifier] options:nil].lastObject;
PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetIdentifier] options:nil].lastObject;
PHAssetCollectionChangeRequest *requestCollection = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
// 添加进自定义的相册
[requestCollection addAssets:@[asset]];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
XMGLOG(@"保存相册成功了 哈哈哈");
}
}];
3.4)1、2、3步合起来的为
__block NSString *assetIdentifier = nil;
__block NSString *collectionIdentifier = nil;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// 1.将图片保存到相簿
assetIdentifier = [PHAssetCreationRequest creationRequestForAssetFromImage:self.downloadImage].placeholderForCreatedAsset.localIdentifier;
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
// 2.创建自定义的相薄
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
collectionIdentifier = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:collectionTitle].placeholderForCreatedAssetCollection.localIdentifier;
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// 3. 将相片保存到自定义的相薄
PHAssetCollection *collection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[collectionIdentifier] options:nil].lastObject;
PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetIdentifier] options:nil].lastObject;
PHAssetCollectionChangeRequest *requestCollection = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
// 添加进自定义的相册
[requestCollection addAssets:@[asset]];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
XMGLOG(@"保存相册成功了 哈哈哈");
}
}];
}
}];
}
}];
3.4) 到这里 我和大家一样 以为我们大功告成了 但是我运行app确实发现是可以保存到自定义的相簿了 系统的相簿也可以保存了 但是当我保存第二张图片的时候发现创建两个自定义相簿(而且每一个相簿只保存一张图片,开始的想法是保存我们的collectiontitle到沙盒,但是我们卸了app在重新装上还是有这个问题的)下面的代码我修改了这个bug
__block PHAssetCollection *collection = nil;
// 获取所有的自定义的相簿
PHFetchResult<PHAssetCollection *> *results = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
for (PHAssetCollection *getCollection in results) {
// 如果有我们要的名字说明存在我们之前创建过的相簿
if ([getCollection.localizedTitle isEqualToString:collectionTitle])
collection = getCollection;
}
}
3.5 所以我们需要对第二步和第三步进行修改
// 第二步修改为
if (!collection) {
collectionIdentifier = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:collectionTitle].placeholderForCreatedAssetCollection.localIdentifier;
}
// 第三步修改为
// 3. 将相片保存到自定义的相薄
if (!collection) {
collection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[collectionIdentifier] options:nil].lastObject;
}
PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetIdentifier] options:nil].lastObject;
PHAssetCollectionChangeRequest *requestCollection = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
// 添加进自定义的相册
[requestCollection addAssets:@[asset]];
3.6)最后我们的综合的代码
__block PHAssetCollection *collection = nil;
PHFetchResult<PHAssetCollection *> *results = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
for (PHAssetCollection *getCollection in results) {
if ([getCollection.localizedTitle isEqualToString:collectionTitle]) {
collection = getCollection;
}
}
__block NSString *assetIdentifier = nil;
__block NSString *collectionIdentifier = nil;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// 1.将图片保存到相簿
assetIdentifier = [PHAssetCreationRequest creationRequestForAssetFromImage:self.downloadImage].placeholderForCreatedAsset.localIdentifier;
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
// 2.创建自定义的相薄
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
if (!collection) {
collectionIdentifier = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:collectionTitle].placeholderForCreatedAssetCollection.localIdentifier;
}
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// 3. 将相片保存到自定义的相薄
if (!collection) {
collection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[collectionIdentifier] options:nil].lastObject;
}
PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetIdentifier] options:nil].lastObject;
PHAssetCollectionChangeRequest *requestCollection = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
// 添加进自定义的相册
[requestCollection addAssets:@[asset]];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
XMGLOG(@"保存相册成功了 哈哈哈");
}
}];
}
}];
}
}];
3.7)说明:现在可以说我们终于写完了 ,但是我还发现了一个小的小问题就是手机系统点击“+”创建相簿还可以创建和我们一样名字的相簿 我想了想 :这个是系统的问题我们管不着(我个人觉得苹果这点不好)我们的现在的代码block嵌套block 看起来不好 大家可以自己整理一下
3.8)如果还有不明白的 请看我的demo(搜索这个类XMGPhotoWatchViewController)
[链接]https://github.com/liudiange/practice1.git