'Select an image from the camera roll and save it to the app
I'm trying to figure out how to save an image that a user selected in a UIImagePickerController from their camera roll into UserDefaults inside of the app. The UIImagePickerController has been set up as such:
@IBAction func addPhotoButton(_ sender: Any) {
let picker = UIImagePickerController()
picker.allowsEditing = true
picker.delegate = self
picker.mediaTypes = ["public.image"]
present(picker, animated: true)
}
The picker itself displays correctly, however I'm looking for assistance in grabbing the image the user selects, and saving it to UserDefaults (or Core Data if UserDefaults is impossible).
The results I found online always yield errors such as:
Cannot find "image" in scope.
To clarify, what I'm looking for assistance in is saving an image to the app via UserDefaults that was selected from UIImagePickerController
Thanks!
Solution 1:[1]
To get the image on gallery tap just implement the delegate method of UIImagePickerController,didFinishPickingMediaWithInfo
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
image.storeInUserDefaults(for: "yourKey")
}
dismiss(animated: true, completion: nil)
}
And to store / get the image you saved in UserDefaults as you asked you can use this extension:
extension UIImage {
func storeInUserDefaults(with compressionQuality: CGFloat = 0.8, for key: String) {
guard let data = self.jpegData(compressionQuality: compressionQuality) else { return }
let encodedImage = try! PropertyListEncoder().encode(data)
UserDefaults.standard.set(encodedImage, forKey: key)
}
static func loadFromUserDefaults(with key: String) throws -> UIImage? {
guard let data = UserDefaults.standard.data(forKey: key) else {
return nil
}
do {
let decodedImageData = try PropertyListDecoder().decode(Data.self, from: data)
return UIImage(data: decodedImageData)
} catch let error {
throw error
}
}
}
Solution 2:[2]
Confirm to 'UIImagePickerControllerDelegate' delegate.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
let imageToBeSaved = image
UIImageWriteToSavedPhotosAlbum(imageToBeSaved, nil, nil, nil)
}
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
let imageToBeSaved = image
UIImageWriteToSavedPhotosAlbum(imageToBeSaved, nil, nil, nil)
}
}
UIImageWriteToSavedPhotosAlbum this will save to photos album, gallery.
Alternatively, it can be stored in application storage too.
static func saveImageToTemp(image: UIImage, withName name: String) -> String? {
let data = image.jpegData(compressionQuality: 0)
let cache = try? FileManager.default.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: false)`enter code here`
if let filename = cache?.appendingPathComponent(name) {
try? data?.write(to: filename)
return filename.absoluteString
}
return nil
}
static func getImage(fromPath path: String) -> UIImage? {
if FileManager.default.fileExists(atPath: path) {
if let image = UIImage(contentsOfFile: path) {
return image
}
}
return nil
}
static func deleteFile(atPath path: String) {
if FileManager.default.fileExists(atPath: path) {
try? FileManager.default.removeItem(atPath: path)
}
}
static func deleteFile(withName name: String) {
let cache = try? FileManager.default.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
if let fileURL = cache?.appendingPathComponent(name) {
if FileManager.default.fileExists(atPath: fileURL.path) {
do {
try FileManager.default.removeItem(atPath: fileURL.path)
} catch {
print("\(#function): Error \(error)")
}
}
}
}
Types of directory available in iOS
static let documents = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
static let library = try? FileManager.default.url(for: .libraryDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
static let downloads = try? FileManager.default.url(for: .downloadsDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
static let user = try? FileManager.default.url(for: .userDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
static let cache = try? FileManager.default.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Alastar |
| Solution 2 |
