0

What's the disadvantage of saving images to NSUserDefault compared to Core Data? Why is it not the best practice to save images in NSUserDefault?

I know saving data in NSUserDefault is by NSData. But it's same in Core Data. So how about the speed compared with NSUserDefault and Core Data?

Sorry about that I don't provide code here.

allenlinli
  • 2,066
  • 3
  • 27
  • 49
  • 3
    Apple says: "The defaults system allows an application to customize its behavior to match a user’s preferences." `NSUserDefaults` is for saving defaults to a plist - user preferences for your app, things like that. *Not* for asset storage. – Eric Aya Aug 07 '16 at 10:58
  • 1
    Yes, I just can not see any actual disadvantage of using it. – allenlinli Aug 07 '16 at 11:13
  • 2
    Because NSUserDefaults is just a monolithic file. Storing your image assets in there would cause performance problems, for example. And security issues. And a possible App Store rejection. And many other reasons to not fight the frameworks and to use them as intended instead. – Eric Aya Aug 07 '16 at 11:16
  • there is __no__ advantage to store any blob in `NSUserDefaults` at all. how did such idea pop into your mind? – holex Aug 12 '16 at 13:20
  • I just want to save 5 photos and some key words in my userdefault. I am not sure it's a good idea or not... – allenlinli Aug 12 '16 at 13:26
  • Don't do it - it's the wrong place. You can store the filenames there and just store them as ordinary files. No need for CoreData here. – Eiko Aug 13 '16 at 07:51

1 Answers1

3

NSUserDefaults is explicitly meant for storing user defaults – images don't belong there especially because NSUserDefaults writes information into a .plist file. Raw image data does not belong into .plist files. Apart from that, it is also not very efficient: the more information you store in a .plist file, the longer it takes to load it. If you want to load a specific image, you would have to load the entire .plist file – including all the other images you don't need at the moment. Briefly speaking: don't do it.

A more appropriate and also more efficient approach for storing your images is to store them in your application's documents directory – where they belong to.

You could do that like this:

Storing your image

func saveImage(image: UIImage, fileName: String) {
        let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
        let path = documentsURL?.appendingPathComponent(fileName)

        do {
            try UIImagePNGRepresentation(image)?.write(to: path!)
        } catch {
            // Handle possible errors here
            print(error.localizedDescription)
        }
    }

Calling your saveImage function

let theImage = UIImage(named: "yourImage")
saveImage(image: theImage!, fileName: "yourImageName")

After storing your images to your application's documents directory, you could take your image's file path and store it in your CoreData database for retrieving the image later.

CoreData can also automate this for you with a little trick. By enabling the "Allows External Storage" checkbox for your binary data attribute, CoreData will store the image somewhere on your device and will only keep a reference to the image in your database (rather than the actual image), in order to keep the performance high. Here's some more information about that.

Community
  • 1
  • 1
Marcel Voss
  • 360
  • 2
  • 9