Error when trying to save a captured image in swift
The problem is that you have never given self.assetCollection
or self.photoAsset
any value, so they are nil. Thus, when you try to use them in your PHAssetCollectionChangeRequest initializer, you crash.
By the way, if all you want to do is save the image into the camera roll, you don't need all that code. The creation request alone is all you need.
Or, if you want to save the image into the camera roll and into an album, you don't need to call PHAssetCollectionChangeRequest(forAssetCollection:assets:)
to do it.
Finally, you really shouldn't have all that extra stuff in the change block. Just do the change and no more. The other stuff should be in the completion block.
Take a photo and save to photo library in Swift
Use below code for an image taken from Photo Gallery and save inside photo library.
Code Support for Swift 3.1 & 4.0 version:
First, we have to do the setup for Permissions inside Project's .plist file:-
1) Camera
<key>NSCameraUsageDescription</key>
<string>This app will use camera.</string>
2) Photo Library
<key>NSPhotoLibraryUsageDescription</key>
<string>You can select photos to attach to reports.</string>
3) Save to Photo Library
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Please allow access to save photo in your photo library</string>
We need to open .pilst file as a Source code type then add permissions inside -
After That
import UIKit
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
@IBOutlet weak var imageTake: UIImageView!
var imagePicker: UIImagePickerController!
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK: - Take image
@IBAction func takePhoto(_ sender: UIButton) {
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera
present(imagePicker, animated: true, completion: nil)
}
//MARK: - Saving Image here
@IBAction func save(_ sender: AnyObject) {
UIImageWriteToSavedPhotosAlbum(imageTake.image!, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)
}
//MARK: - Add image to Library
func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
if let error = error {
// we got back an error!
let ac = UIAlertController(title: "Save error", message: error.localizedDescription, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
} else {
let ac = UIAlertController(title: "Saved!", message: "Your altered image has been saved to your photos.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
}
}
//MARK: - Done image capture here
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
imagePicker.dismiss(animated: true, completion: nil)
imageTake.image = info[UIImagePickerControllerOriginalImage] as? UIImage
}
}
Swift 4.2 Code update -
class ViewController: UIViewController, UINavigationControllerDelegate {
@IBOutlet weak var imageTake: UIImageView!
var imagePicker: UIImagePickerController!
enum ImageSource {
case photoLibrary
case camera
}
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK: - Take image
@IBAction func takePhoto(_ sender: UIButton) {
guard UIImagePickerController.isSourceTypeAvailable(.camera) else {
selectImageFrom(.photoLibrary)
return
}
selectImageFrom(.camera)
}
func selectImageFrom(_ source: ImageSource){
imagePicker = UIImagePickerController()
imagePicker.delegate = self
switch source {
case .camera:
imagePicker.sourceType = .camera
case .photoLibrary:
imagePicker.sourceType = .photoLibrary
}
present(imagePicker, animated: true, completion: nil)
}
//MARK: - Saving Image here
@IBAction func save(_ sender: AnyObject) {
guard let selectedImage = imageTake.image else {
print("Image not found!")
return
}
UIImageWriteToSavedPhotosAlbum(selectedImage, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)
}
//MARK: - Add image to Library
@objc func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
if let error = error {
// we got back an error!
showAlertWith(title: "Save error", message: error.localizedDescription)
} else {
showAlertWith(title: "Saved!", message: "Your image has been saved to your photos.")
}
}
func showAlertWith(title: String, message: String){
let ac = UIAlertController(title: title, message: message, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
}
}
extension ViewController: UIImagePickerControllerDelegate{
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){
imagePicker.dismiss(animated: true, completion: nil)
guard let selectedImage = info[.originalImage] as? UIImage else {
print("Image not found!")
return
}
imageTake.image = selectedImage
}
}
Error Saving Image to Photo Library iOS/Mac Catalyst App Swift
I was able to save the images to MacOS through this Mac Catalyst App using the following code in Swift;
func insertImageMac(image : UIImage, albumName : String) {
let collection = fetchAssetCollectionWithAlbumName(albumName: albumName)
if collection == nil {
PHPhotoLibrary.shared().performChanges({
PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: albumName)
}, completionHandler: {(success, error) in
if error != nil {
print("Error: " + error!.localizedDescription)
}
if success {
let newCollection = self.fetchAssetCollectionWithAlbumName(albumName: albumName)
self.insertImage(image: image, intoAssetCollection: newCollection!)
}
}
)
} else {
self.insertImage(image: image, intoAssetCollection: collection!)
}
}
func fetchAssetCollectionWithAlbumName(albumName : String) -> PHAssetCollection? {
let fetchOption = PHFetchOptions()
fetchOption.predicate = NSPredicate(format: "title == '" + albumName + "'")
let fetchResult = PHAssetCollection.fetchAssetCollections(
with: PHAssetCollectionType.album,
subtype: PHAssetCollectionSubtype.albumRegular,
options: fetchOption)
let collection = fetchResult.firstObject as? PHAssetCollection
return collection
}
func insertImage(image : UIImage, intoAssetCollection collection : PHAssetCollection) {
PHPhotoLibrary.shared().performChanges({
let creationRequest = PHAssetCreationRequest.creationRequestForAsset(from: image)
let request = PHAssetCollectionChangeRequest(for: collection)
if request != nil && creationRequest.placeholderForCreatedAsset != nil {
request!.addAssets([creationRequest.placeholderForCreatedAsset!] as NSFastEnumeration)
}
},
completionHandler: { (success, error) in
if error != nil {
print("Error: " + error!.localizedDescription)
let ac = UIAlertController(title: "Save error", message: error!.localizedDescription, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "Done", style: .default))
self.present(ac, animated: true)
} else {
let ac = UIAlertController(title: "Save success", message: "Image saved", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "Done", style: .default))
self.present(ac, animated: true)
}
}
)
}
...and calling it inside my button function with the image;
insertImageMac(image: myImage, albumName: "AlbumName")
UIImage not saving to Camera Roll
I was able to solve the issue using this code:
@IBAction func SaveTapped(sender: AnyObject) {
let softwareContext = CIContext(options: [kCIContextUseSoftwareRenderer:true])
let cgimg = softwareContext.createCGImage(savedImage,
fromRect: savedImage.extent())
let libary = ALAssetsLibrary()
libary.writeImageToSavedPhotosAlbum(cgimg, metadata: savedImage.properties(),
completionBlock: nil)
}
Related Topics
Array Element Checking in Swift
How to Authorize Twitter with Swifter
How to Properly Refresh a Uinavigationbar
Exc_Breakpoint (Sigtrap) on Production Version Only
Collectionview Flowlayout Overlapping When Scrolling Not Working
In Swift, for Anyobject, How to Setvalue() Then Call Valueforkey()
Save Struct in Class to Nsuserdefaults Using Swift
Uialertcontroller Title and Message Not Appearing
Swift/How to Call Delegate with Popviewcontroller
Target Is Not Found, Please Reconnect the Device, Xcode:Device Support File
Swiftui Animation and Subsequent Reverse Animation to Original State
Nsfetchedresultscontroller Swift Sections
Using Simple Ping in Swift (Ios)
How to Load Thousands Records to Realm Correctly
Countdown with Several Decimal Slots, Using Nstimer in Swift