TituJow
TituJow

Reputation: 129

What am I doing wrong on try to save image in USerDefault

I gotta get an image then save it to UserDefaults to be able to retrieve it. However, I tried by saving as UIImage but when I try to retrieve the image the app crashes. How would be the best way for me to do that?

That's how I'm trying to save the picture.

import UIKit

protocol dataReceivedDelegate {
    func dataReceived(fotoSaved:[UIImage],nameSaved:NSArray)
}

class adicionarNovoItemVc: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UITextFieldDelegate {

    @IBOutlet weak var textFieldNome: UITextField!
    let imagePicker = UIImagePickerController()
    @IBOutlet weak var namePreview: UILabel!
    @IBOutlet weak var imagePreview: UIImageView!
    let picker = UIImagePickerController()
    var arrayName = [String]()
    var arrayFoto = [UIImage]()
    var delegate:dataReceivedDelegate? = nil

    override func viewDidLoad() {
        super.viewDidLoad()
        self.textFieldNome.delegate = self
        // Do any additional setup after loading the view.
        if isKeyPresentInUserDefaults(key: "namesSavedArray") == true{
            arrayName = UserDefaults.standard.array(forKey: "namesSavedArray") as! [String]
        }
        if isKeyPresentInUserDefaults(key: "fotoSavedArray") == true{
            arrayFoto = UserDefaults.standard.array(forKey: "fotoSavedArray") as! [UIImage]
        }
    }
    func isKeyPresentInUserDefaults(key: String) -> Bool {
        return UserDefaults.standard.object(forKey: key) != nil
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let image = info[.originalImage] as? UIImage {
            self.imagePreview.image = image
            self.namePreview.text = self.textFieldNome.text
        }
        self.picker.dismiss(animated: true, completion: nil)
    }


    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        self.textFieldNome.resignFirstResponder()
        return true
    }

    @IBAction func botaoAdcItem(_ sender: UIButton) {
        if (self.namePreview!.text != nil) && (self.imagePreview!.image != nil) {
            if delegate != nil {

                arrayName.append(self.namePreview.text!)
                arrayFoto.append(self.imagePreview.image!)

                delegate?.dataReceived(fotoSaved: arrayFoto, nameSaved: arrayName as NSArray)

                UserDefaults.standard.set(arrayName, forKey: "namesSavedArray")
                UserDefaults.standard.set(arrayFoto, forKey: "fotoSavedArray")

            self.navigationController?.popViewController(animated: true)
            }
        }
        else {return}
}

Upvotes: 0

Views: 626

Answers (2)

Christian Abella
Christian Abella

Reputation: 5797

As @Duncan-c have said, you should not save it in UserDefaults. You can save the selected filename (URL) though in UserDefaults and load the actual image using the filename (URL) next time you want to use it.

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
  if let imageURL = info[UIImagePickerControllerImageURL] as! URL? {
    UserDefaults.standard.set(imageURL, forKey: "SelectedImage")
    UserDefaults.standard.synchronize()
  }

  ...  
  picker.dismiss(animated: true, completion: nil)

}

// Load the image
if let imageURL = UserDefaults.standard.url(forKey: "SelectedImage") {
   if let data = NSData(contentsOf: imageURL) as NSData? {
      self. imagePreview.image = UIImage(data: data as Data)
   }
}

Upvotes: 0

Duncan C
Duncan C

Reputation: 131398

You cannot, and should not, store images to UserDefaults. UserDefaults is intended to hold short things like user inputted strings or preference settings.

It can only save a short list of data types ("property list" objects: Array, Dictionary, String, Data, Date, integer types, floating point types, or Bools). Any other data type will fail.

I suggest saving the image to the user's Documents directory and then saving a path to the file in UserDefaults.

Upvotes: 2

Related Questions