3

I'm trying to save users image to userDefaults but i'm always getting error "Thread 1: "Attempt to insert non-property list object (Function) for key savedimage" Here's my code

import UIKit

class productSelectionPage: UIViewController {
    @IBOutlet weak var productImageView: UIImageView!


    override func viewDidLoad() {
        super.viewDidLoad()

        // Save image
        let image = UIImage(named: "user")
        let imageData = UIImage.jpegData(image)
        UserDefaults.standard.setValue(imageData, forKey: "savedImage")

    }
    @IBAction func offerButtonTapped(_ sender: UIButton) {
        // present image
        let imageData = UserDefaults.standard.object(forKey: "savedImage")
        let image = UIImage(data: (imageData as! NSData) as Data)
        productImageView.image = image
        // crash

        
        
    }
    

}

3 Answers3

9

Try to use PropertyListEncoder() and Decoder like this:

func saveImage() {
    guard let data = UIImage(named: "image").jpegData(compressionQuality: 0.5) else { return }
    let encoded = try! PropertyListEncoder().encode(data)
    UserDefaults.standard.set(encoded, forKey: "KEY")
}

func loadImage() {
     guard let data = UserDefaults.standard.data(forKey: "KEY") else { return }
     let decoded = try! PropertyListDecoder().decode(Data.self, from: data)
     let image = UIImage(data: decoded)
}
Daveloper
  • 606
  • 5
  • 12
1

If you have ever used firebase, you would understand that all images and videos are saved as data, not as pixels.

A similar approach is taken when saving to UserDefaults

// storing the image data

private func store(image: UIImage, forKey key: String, withStorageType storageType: StorageType) {

    if let pngRepresentation = image.pngData() {
        
            UserDefaults.standard.set(pngRepresentation, forKey: key)
        
    }
}

// retrieving the image data and getting an image

To retrieve it, we will take that image data

    private func retrieveImage(forKey key: String, inStorageType storageType: StorageType) -> UIImage? {
    
        if let imageData = UserDefaults.standard.object(forKey: key) as? Data, 
            let image = UIImage(data: imageData) {
            
            return image
        }
    }
}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Denzel
  • 309
  • 1
  • 8
-1

You can just simply convert Image into Data as shown in the extension for UIImageView like below code

//MARK: -|||-To Store Image in Userdefault You can just Simply create an uiimageview extension-||| -
extension UIImageView{
    func saveImage(){
    guard let image = self.image, let data = image.jpegData (compressionQuality: 0.5) else { return }
      let encoded = try! PropertyListEncoder ().encode (data)
      UserDefaults.standard.set(encoded, forKey: "image")
    }
    func loadImage() {
        guard let data = UserDefaults.standard.data(forKey: "image") else { return }
        let decoded = try! PropertyListDecoder().decode(Data.self, from: data)
        let image = UIImage(data: decoded)
        self.image = image
    }
}

Here is how to use this extension:

class ViewController: UViewController {
    @IBOutlet var sendImg: UIImageView!
    @IBOutlet var receiveImg: UlImageView!

    override func viewDidLoad(){
        super.viewDidLoad() {
        sendImg.saveImage()
    }

    @IBAction func loadImageFromUserDefault(_ sender: UIButton) {
        receiveImg.loadImage()
    } 
}

to save image in UserDefault:

yourImage.saveImage()

to get image from UserDefault:

yourImage.loadImage()
N4SK
  • 700
  • 8
  • 25
  • Please add code and data as text ([using code formatting](/editing-help#code)), not images. Images: A) don't allow us to copy-&-paste the code/errors/data for testing; B) don't permit searching based on the code/error/data contents; and [many more reasons](//meta.stackoverflow.com/a/285557). Images should only be used, in addition to text in code format, if having the image adds something significant that is not conveyed by just the text code/error/data. – Suraj Rao May 20 '22 at 05:39