当前位置: > > > Swift - 使用Photos框架(PhotoKit)将图片保存到自定义相簿

Swift - 使用Photos框架(PhotoKit)将图片保存到自定义相簿

(本文代码已升级至Swift3)
 
在iOS 8之前,开发者只能用 AssetsLibrary 框架访问的用户的照片库。几年以来,相机应用和照片应用发生了显著的变化,增加了许多新特性,包括按时刻来组织照片的方式。但与此同时,AssetsLibrary 框架却没有跟上步伐。
随着 iOS 8 的到来,苹果给我们提供了一个现代化的框架 PhotoKit,它比 AssetsLibrary 表现更好,并且拥有让应用和设备照片库无缝工作的特性。

在之前的文章里(Swift - 保存图片到系统相册(相机胶卷),并获取存放路径、缩略图)我简单地介绍了Photos框架(PhotoKit)的使用,当时是把图片保存到相机胶卷中。本文介绍如何把图像保存到指定的自定义相簿(自定义相册)中去。

1,为方便使用,封装一个工具类(PhotoAlbumUtil.swift)
(1)保存时会先验证用户是否授权操作相册照片。
(2)指定相簿名字,即可将图片保存到该相簿下。(如果相簿不存在,也会自动创建)
(3)如果不指定相簿名字,则保存到相机胶卷中。
(4)保存后会有回调函数,可以用来判读是否保存成功、还是失败、或是没有操作照片相册的权限。
import Photos

//操作结果枚举
enum PhotoAlbumUtilResult {
    case success, error, denied
}

//相册操作工具类
class PhotoAlbumUtil: NSObject {
    
    //判断是否授权
    class func isAuthorized() -> Bool {
        return PHPhotoLibrary.authorizationStatus() == .authorized ||
            PHPhotoLibrary.authorizationStatus() == .notDetermined
    }
    
    //保存图片到相册
    class func saveImageInAlbum(image: UIImage, albumName: String = "",
                                completion: ((_ result: PhotoAlbumUtilResult) -> ())?) {
        
        //权限验证
        if !isAuthorized() {
            completion?(.denied)
            return
        }
        var assetAlbum: PHAssetCollection?
        
        //如果指定的相册名称为空,则保存到相机胶卷。(否则保存到指定相册)
        if albumName.isEmpty {
            let list = PHAssetCollection
                .fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary,
                                               options: nil)
            assetAlbum = list[0]
        } else {
            //看保存的指定相册是否存在
            let list = PHAssetCollection
                .fetchAssetCollections(with: .album, subtype: .any, options: nil)
            list.enumerateObjects({ (album, index, stop) in
                let assetCollection = album
                if albumName == assetCollection.localizedTitle {
                    assetAlbum = assetCollection
                    stop.initialize(to: true)
                }
            })
            //不存在的话则创建该相册
            if assetAlbum == nil {
                PHPhotoLibrary.shared().performChanges({
                    PHAssetCollectionChangeRequest
                        .creationRequestForAssetCollection(withTitle: albumName)
                }, completionHandler: { (isSuccess, error) in
                    self.saveImageInAlbum(image: image, albumName: albumName,
                                          completion: completion)
                })
                return
            }
        }
        
        //保存图片
        PHPhotoLibrary.shared().performChanges({
            //添加的相机胶卷
            let result = PHAssetChangeRequest.creationRequestForAsset(from: image)
            //是否要添加到相簿
            if !albumName.isEmpty {
                let assetPlaceholder = result.placeholderForCreatedAsset
                let albumChangeRequset = PHAssetCollectionChangeRequest(for:
                    assetAlbum!)
                albumChangeRequset!.addAssets([assetPlaceholder!]  as NSArray)
            }
        }) { (isSuccess: Bool, error: Error?) in
            if isSuccess {
                completion?(.success)
            } else{
                print(error!.localizedDescription)
                completion?(.error)
            }
        }
    }
}
2,将图片保存到指定相簿中
PhotoAlbumUtil.saveImageInAlbum(image: image, albumName: "航歌") { (result) in
    switch result{
    case .success:
        print("保存成功")
    case .denied:
        print("被拒绝")
    case .error:
        print("保存错误")
    }
}
可以看到图片已经保存到“航歌”这个相簿中来了:


3,将图片保存到相机胶卷中
如果参数 albumName 不指定相簿名字,则默认保存到相机胶卷中去。
PhotoAlbumUtil.saveImageInAlbum(image: image) { (result) in
    switch result{
    case .success:
        print("保存成功")
    case .denied:
        print("被拒绝")
    case .error:
        print("保存错误")
    }
}

4,获取保存后的路径、原图、缩略图
方法可以参考我之前的文章,这里就不再写了:Swift - 保存图片到系统相册(相机胶卷),并获取存放路径、缩略图
评论4
  • 4楼
    2016-06-22 10:08
    ustclsl

    再请教一个问题。我用ALAssetsLibrary获取的所有视频名字,全是一样的,都是应用的名称。是怎么回事?

    站长回复

    用ALAssetsLibrary是可以获取到视频名字的,可能你哪里写错了。你参考我原来写的这篇文章看看:Swift - 使用ALAssetsLibrary获取相簿里所有图片,视频(附样例)

  • 3楼
    2016-05-10 00:44
    xiongq

    航哥 视频该如何保存

    站长回复

    过几天我会写篇录像相关的文章,里面会有视频保存,你可以关注下。

  • 2楼
    2016-05-09 09:45
    ustclsl

    你好,请问这个框架能修改系统视频的文件名字吗?

    站长回复

    就我所知,这个改不了文件名。

  • 1楼
    2016-04-14 20:09
    liuwei

    航哥,下面这两个是leancloud网站短信文档里的短信验证方法。。但是我没学过oc,可不可以帮我翻译成swift??
    AVUser requestMobilePhoneVerify:@"18612345678" withBlock:^(BOOL succeeded, NSError *error) {
    if(succeeded){
    //发送成功
    }
    }];
    [AVUser verifyMobilePhone:@"123456" withBlock:^(BOOL succeeded, NSError *error) {
    if(succeeded){
    //验证成功
    }
    }];

    站长回复

    leancloud我没用过,不过上面代码翻译成的Swift代码见下方:
    AVUser.requestMobilePhoneVerify("18612345678") { (succeeded, error) in
        if(succeeded){
            //发送成功
        }
    }

    AVUser.verifyMobilePhone("123456") { (succeeded, error) in
        if(succeeded){
            //验证成功 
        }
    }