0

I need to persist an array of custom objects from session to session for a user. The array will be filled with 1-14 fairly simple and lightweight custom swift objects like so:

[Obj1, Obj2, Obj3]

What I want to do is when viewWillDisappear is called, persist this data so that when the user comes back to the screen, I can use these exact objects again. What is the best way to do this? I've looked into using core data, but I don't want to setup a data model for these objects, just store them as is without any relationships or anything.

Please note that the app makes use of a very computationally taxing algorithm, of which these objects play a central role. As such, I need to keep these objects as light as possible. Therefore, I don't want to make the objects conform to NSCoding as it isn't necessary to the central role of the object

James Stonehill
  • 1,125
  • 10
  • 22
  • 1
    "Please note that for various reasons these objects are not suitable to be stored in NSUserdefaults." I'd be interested to hear those, because that would be my go-to solution – Alexander Dec 28 '16 at 21:36
  • 2
    You could use NSCoding + NSKeyedArchiver – Eric Aya Dec 28 '16 at 21:38
  • Use `NSCoding`, see a similar approach here: [Writing swift dictionary to file](http://stackoverflow.com/q/27197658/2415822) – JAL Dec 28 '16 at 21:39
  • @Alexander. In answer to your question, the app makes use of a very computationally taxing algorithm, of which these objects play a central role. As such, I need to keep these objects as light as possible. Therefore, I don't want to make the objects conform to NSCoding as it isn't necessary to the central role of the object. – James Stonehill Dec 28 '16 at 21:41
  • If you don't want to make the objects conform to `NSCoding` then I think you fail to grasp the concept of [serialization](https://en.wikipedia.org/wiki/Serialization). `NSCoding` is how that works on iOS. Or make a storage wrapper class that conforms to `NSCoding` which holds the array. – JAL Dec 28 '16 at 21:43
  • 2
    @JamesStonehill You can make a NSCoding subclass that's used solely for storage, and make your current lightweight Swift objects have an initializer that takes the container object. – Alexander Dec 28 '16 at 21:43

2 Answers2

2

If making your class an Objective-C class that conforms to NSCoding proves to actually have a substantial performance impact (I'm skeptical), then you can make a second container that subclasses NSCoding that's used solely for storage. Add an initializer to your current lightweight Swift class/struct that initializes the instance from this container object, and vice versa. Any time you need to serialize/deserialize, you just use this container object as an intermediate.

This buys you the functionality at minimal cost when reading/writing, but leaves regular usage performance unaffected.

Alexander
  • 59,041
  • 12
  • 98
  • 151
  • How would adding another layer on top of `NSCoding` improve performance? I'm not sure I understand why one would do that. – sbooth Dec 28 '16 at 22:00
  • @sbooth Objective C classes always use dynamic dispatch. The compiler can't inline any methods, trim unused code, or do any optimizations that require looking "into" method calls. – Alexander Dec 28 '16 at 22:01
  • @sbooth Thus, it maybe beneficial to take a hit any time an object is serialized/deserialized due to this extra middleman logic, but then benefit from faster performance during the rest of the time – Alexander Dec 28 '16 at 22:04
0

If you can make the object a subclass of NSObject then you can have it conform to NSCoding and use NSKeyedArchiver and NSKeyedUnarchiver to serialize and deserialize your objects.

Duncan C
  • 128,072
  • 22
  • 173
  • 272