Error when trying to save image in NSUserDefaults using Swift
Asked Answered
F

4

9

When i try to save an image in NSUserDefaults, the app crashed with this error.

Why? Is it possible to save an image with NSUserDefaults? If not, then how do I save the image?

Image...

Xcode error

Code...

var image1:UIImage = image1

var save1: NSUserDefaults = NSUserDefaults.standardUserDefaults()

save1.setObject(Info.Image1, forKey: "Image1")       

save1.synchronize()

Log error...

libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)

Firecrest answered 1/4, 2015 at 23:10 Comment(0)
F
22

NSUserDefaults isn't just a big truck you can throw anything you want onto. It's a series of tubes which only specific types.

What you can save to NSUserDefaults:

  • NSData
  • NSString
  • NSNumber
  • NSDate
  • NSArray
  • NSDictionary

If you're trying to save anything else to NSUserDefaults, you typically need to archive it to an NSData object and store it (keeping in mind you'll have to unarchive it later when you need it back).


There are two ways to turn a UIImage object into data. There are functions for creating a PNG representation of the image or a JPEG representation of the image.

For the PNG:

let imageData = UIImagePNGRepresentation(yourImage)

For the JPEG:

let imageData = UIImageJPEGRepresentation(yourImage, 1.0)

where the second argument is a CGFloat representing the compression quality, with 0.0 being the lowest quality and 1.0 being the highest quality. Keep in mind that if you use JPEG, each time you compress and uncompress, if you're using anything but 1.0, you're going to degrade the quality over time. PNG is lossless so you won't degrade the image.

To get the image back out of the data object, there's an init method for UIImage to do this:

let yourImage = UIImage(data:imageData)

This method will work no matter how you converted the UIImage object to data.

In newer versions of Swift, the functions have been renamed, and reorganized, and are now invoked as:

For the PNG:

let imageData = yourImage.pngData()

For the JPEG:

let imageData = yourImage.jpegData(compressionQuality: 1.0)

Although Xcode will autocorrect the old versions for you

Forepleasure answered 1/4, 2015 at 23:17 Comment(0)
R
8

In order to save UIImage in NSUserDefaults, you need to convert UIImage into NSData using UIImageJPEGRepresentation(image, 1) then save it in NSUserDefaults. And on the other side, while retrieving it on another ViewController (within that same application) you need to get NSData and then convert it into UIImage.

Here i am writing small code snippet in swift to demonstrate this. I tried this in XCODE 6.4

/*Code to save UIImage in NSUserDefaults on viewWillDisappear() event*/

override func viewWillDisappear(animated: Bool) 
{
        super.viewWillDisappear(animated)
       //Get some image in image variable of type UIImage.
        var image = .... 
        let defaults = NSUserDefaults.standardUserDefaults()
        var imgData = UIImageJPEGRepresentation(image, 1)
        defaults.setObject(imgData, forKey: "image")

}
/*Code to get Image and show it on imageView at viewWillAppear() event*/

override func viewWillAppear(animated: Bool) 
{
    super.viewWillAppear(animated)
    let defaults = NSUserDefaults.standardUserDefaults()
    if let imgData = defaults.objectForKey("image") as? NSData
    {
        if let image = UIImage(data: imgData)
        {
            //set image in UIImageView imgSignature
            self.imgSignature.image = image
            //remove cache after fetching image data
            defaults.removeObjectForKey("image")  
        }
    }
}
Ritual answered 26/10, 2015 at 7:23 Comment(2)
if let imgData = NSUserDefaults.standardUserDefaults().dataForKey("image")Glossectomy
This i have successfully tried in swift 1.0. But you can do this thing also.Ritual
M
3

Updated for Swift 3:

If you want to save image in UserDefault used below lines of code save and retrieve the image;

To Save image in UserDefault:

if let image = response.result.value {
            UserDefaults.standard.register(defaults: ["key":UIImageJPEGRepresentation(image, 100)!])
            UserDefaults.standard.set(UIImageJPEGRepresentation(image, 100), forKey: "key")
        }

To Retrieve the image from UserDefault and set it to ImageView:

var mLogoImageView = UIImageView() 

if let imageData = UserDefaults.standard.value(forKey: "key") as? Data{
            let imageFromData = UIImage(data: imageData)
            mLogoImageView.image = imageFromData!
        }

Enjoy..!

Mccombs answered 20/11, 2017 at 10:26 Comment(0)
G
1

In Swift 4 - 5

Set:

setImage(image: UIImage(named: "12")!)

func setImage(image : UIImage) {
    UserDefaults.standard.set(image.jpegData(compressionQuality: 100), forKey: "key")
}

Get

func getImage() -> UIImage? {
    if let imageData = UserDefaults.standard.value(forKey: "key") as? Data{
        if let imageFromData = UIImage(data: imageData){
            return imageFromData
        }
    }
    return nil
}
Genteel answered 27/7, 2020 at 17:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.