import UIKit import Photos extension PHPhotoLibrary { // MARK: - PHPhotoLibrary+SaveImage // MARK: - Public func savePhoto(image:UIImage, albumName:String, completion:((PHAsset?)->())? = nil) { func save() { if let album = PHPhotoLibrary.shared().findAlbum(albumName: albumName) { PHPhotoLibrary.shared().saveImage(image: image, album: album, completion: completion) } else { PHPhotoLibrary.shared().createAlbum(albumName: albumName, completion: { (collection) in if let collection = collection { PHPhotoLibrary.shared().saveImage(image: image, album: collection, completion: completion) } else { completion?(nil) } }) } } if PHPhotoLibrary.authorizationStatus() == .authorized { save() } else { PHPhotoLibrary.requestAuthorization({ (status) in if status == .authorized { save() } }) } } // MARK: - Private fileprivate func findAlbum(albumName: String) -> PHAssetCollection? { let fetchOptions = PHFetchOptions() fetchOptions.predicate = NSPredicate(format: "title = %@", albumName) let fetchResult : PHFetchResult = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions) guard let photoAlbum = fetchResult.firstObject else { return nil } return photoAlbum } fileprivate func createAlbum(albumName: String, completion: @escaping (PHAssetCollection?)->()) { var albumPlaceholder: PHObjectPlaceholder? PHPhotoLibrary.shared().performChanges({ let createAlbumRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: albumName) albumPlaceholder = createAlbumRequest.placeholderForCreatedAssetCollection }, completionHandler: { success, error in if success { guard let placeholder = albumPlaceholder else { completion(nil) return } let fetchResult = PHAssetCollection.fetchAssetCollections(withLocalIdentifiers: [placeholder.localIdentifier], options: nil) guard let album = fetchResult.firstObject else { completion(nil) return } completion(album) } else { completion(nil) } }) } fileprivate func saveImage(image: UIImage, album: PHAssetCollection, completion:((PHAsset?)->())? = nil) { var placeholder: PHObjectPlaceholder? PHPhotoLibrary.shared().performChanges({ let createAssetRequest = PHAssetChangeRequest.creationRequestForAsset(from: image) guard let albumChangeRequest = PHAssetCollectionChangeRequest(for: album), let photoPlaceholder = createAssetRequest.placeholderForCreatedAsset else { return } placeholder = photoPlaceholder let fastEnumeration = NSArray(array: [photoPlaceholder] as [PHObjectPlaceholder]) albumChangeRequest.addAssets(fastEnumeration) }, completionHandler: { success, error in guard let placeholder = placeholder else { completion?(nil) return } if success { let assets:PHFetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [placeholder.localIdentifier], options: nil) let asset:PHAsset? = assets.firstObject completion?(asset) } else { completion?(nil) } }) } }