Skip to content

Instantly share code, notes, and snippets.

@khorbushko
Created December 29, 2016 09:27
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save khorbushko/f090595f6207f6c93c24f30a30194aac to your computer and use it in GitHub Desktop.
Save khorbushko/f090595f6207f6c93c24f30a30194aac to your computer and use it in GitHub Desktop.
PHPhotoLibrary+SaveImage - save image with Photos Framework swift 3
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> = PHAsset.fetchAssets(withLocalIdentifiers: [placeholder.localIdentifier], options: nil)
let asset:PHAsset? = assets.firstObject
completion?(asset)
} else {
completion?(nil)
}
})
}
}
@rakeshkathoju
Copy link

how to same image to defult camera roll . when gave title it creating new album with camera roll

@jjxtra
Copy link

jjxtra commented Sep 19, 2019

Fun iOS 13 bug, smaller png images with transparency (maybe around under 1024x1024) save as jpegs instead.

@valterandremachado
Copy link

can't call this extension inside of a viewController. I'm getting this error 'NSInternalInconsistencyException', reason: '-[PHPhotoLibrary init] unsupported'. any suggestion?

@Walker123t
Copy link

can't call this extension inside of a viewController. I'm getting this error 'NSInternalInconsistencyException', reason: '-[PHPhotoLibrary init] unsupported'. any suggestion?

Getting the same issue here

@cjmaroney01
Copy link

i have not tried this actual extension code, but i was getting the error 'NSInternalInconsistencyException', reason: '-[PHPhotoLibrary init] unsupported'. and the reason was that i was trying to do "var library: PHPhotoLibrary = PHPhotoLibrary()" instead of using the PHPhotoLibrary.shared(). Maybe not the reason y'all are having the issue, but i'm posting this here because i was getting that same error and resolved it by not doing that.

@oolex2
Copy link

oolex2 commented Jul 20, 2020

Really helpful, thanks a lot for shearing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment