10

I need to store some objects in my app (Xcode 9.1, Swift 4). Currently, I'm storing it like this:

class myItemManager {

    var items: [myItem]? {
        didSet {
            Cache.c.items = items
        }
    }

    static var manager = myItemManager() {
        didSet {
            myItemManager.manager.items = Cache.c.items
        }
    }
}

class Cache {

    private let uds = UserDefaults.standard

    static let c = Cache()

    var items: [(myItem)]? {
        get {
            if let decoded = uds.object(forKey: Constants.Cache.myItem) as? Data {
                let decodedItems = NSKeyedUnarchiver.unarchiveObject(with: decoded) as? [myItem]
                return decodedItems
            } else {
               return nil
            }
        }
        set {
            let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: newValue as AnyObject)
            uds.set(encodedData, forKey: Constants.Cache.myItem)
            uds.synchronize()
        }
    }
}

First, I'm downloading items (from JSON). After I download it, I just save it, like this:

myItemManager.manager.items = downloadedItems

Of course, "myItem" subclasses NSObject and NSCoding (allows to save in UserDefaults).

Is this a good approach? Or should I use Core Data? In the future, I will have to filter this data and present it in UICollectionView.

Bartosz Woźniak
  • 2,065
  • 3
  • 14
  • 31
  • Lots of similar questions with answers: https://stackoverflow.com/search?q=core+data+vs+nsuserdefaults. – Martin R Nov 21 '17 at 12:06
  • To get filter data from the persistence is not supported by the user defaults, you need to implement core data. My suggestion would be use core data, if you don't have knowledge of core data then you should learn it. Once you learned it you will not going to use anything else apart from core data – Inder Kumar Rathore Nov 21 '17 at 12:07
  • To put it short. Use `UserDefaults` in small projects or to store some flags. Use `CoreData` in big projects. Don't use `UserDefaults` to store big data, such as image caching. `CoreData` entities are generally a better design than arbitrary values stored by keys, even if later serialized to objects. – Hexfire Nov 21 '17 at 12:09

2 Answers2

22

NSUserDefaults as the name suggests (vaguely) should be used for storing preferences and app settings only. You should not be storing critical data and or user data into them.

CoreData is a full fledged persistent framework which supports large data transactions. CoreData allows you to build relational entity–attribute model for storing user data.

Please note that CoreData is a framework and can use SQLite, binary formats to store data (the default templates always use SQLite).

Example:

App preferences like show notifications, toggle switch settings, UISegmentedControl settings all go into NSUserDefaults. Whereas any data you might fetch using a web service like a list of all cities in a country, list of todos for a user go into CoreData.

PS: I don't recommend wiki for technical write-ups but to get quick understanding on CoreData, please refer here!

Pros of NSUserDefaults:

  • Easy to store and retrieve data.
  • Useful for storing default values with minimum fuzz.

Cons of NSUserDefaults:

  • Not suitable for large data sets

  • Performance hit when you try to store and load large amount of data All or nothing approach

Pros of CoreData:

  • Reliable framework to interact and query against data

  • Can be extremely fast when setup correctly (with relationships)

  • Powerful capabilities

Cons of CoreData

  • Takes time to master and learn the core concept

  • Needs proper app architecture design to be efficient

  • You cannot have a learn and implement in a day approach with CoreData

  • As you improve your app, you need to improve your data architecture as well

  • Migrating to new versions can be a pain if you are not careful.

Reference From HERE.

Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
2

If the data has nothing to do with user preferences, then don't store it there. What about serialising the data to an external file in your container before going the full monty with Core Data?

mschmidt
  • 2,740
  • 4
  • 17
  • 31