0

I'm writing a glorified 'paint' application where a user can paste in images, and draw a bunch of UIBezier curves, and move all these things around and rotate them.

Most of these are implemented by stacking UIImageViews and (sub-classed) UIViews as subviews onto the main view in the view controller.

I want the user to be able to save the state of their creation as some kind of file and share it with others (e.g. via DropBox).

The saving itself isn't the issue (I know how to save files!), just the 'best' way to get all the information from the app into file(s) and then load it back in.

I'm guessing there are already well-established frameworks for doing exactly this, but oddly, haven't found anything that addresses this.

So, before I set about writing my own custom methods for doing all this, I thought I'd ask:

Is there some recommended, approved (and maybe even 'easy' ;-)) way to implement saving -- as in writing to files -- the state of all the subviews of a given UIView?

Your recommendations for what I'm "trying to do"? Thanks.

sh37211
  • 1,411
  • 1
  • 17
  • 39
  • Maybe this is just a sub-case of writing out all the contents of ANY class...I'm reading about Core Data, and methods for "persistence", and NSUserDefaults, and such. But it seems like it should be unnecessary -- why should I need to create a parallel set of NSManagedObjects (which seems wasteful if there are large images involved) when all the "data" I want to save is already stored nicely in the ViewController hierarchy? – sh37211 Aug 22 '15 at 21:30

1 Answers1

0

tl;dr

Going Down:
NSKeyedArchiver.archiveRootObject(view, toFile: "/path/to/archive")

Coming Up:
let view = NSKeyedUnarchiver.unarchiveObjectWithFile("/path/to/archive")

UIView Documentation)

UIView conforms to NSCoding

enter image description here

NSCoding enables the creation of archives, which

provide a means to convert objects and values into an architecture-independent stream of bytes.

Now we have all the pieces to the puzzle, let's put them together:

We know we're going to need an archiver, so let's search the docs until we find something promising: enter image description here

Bingo! NSKeyedArchiver

Let's use this class to serialize a UIView to a file with archiveRootObject:toFile:. Then we'll deserialize it from a file with unarchiveObjectWithFile:.

Saving to file:
NSKeyedArchiver.archiveRootObject(view, toFile: "/path/to/archive")

Reading from file:
let view = NSKeyedUnarchiver.unarchiveObjectWithFile("/path/to/archive")

Nathan Hillyer
  • 1,959
  • 1
  • 18
  • 22
  • Yes. (Ignore earlier comments about segfaults.) I'm finding that for ordinary UIImageView objects your method works GREAT, but if I sub-class UIImageView at all, then what gets loaded back (after saving & reading) is just a big black rectangle (not the correct image) with no properties. I've implemented both super.init(coder: coder) and super.encodeWithCoder(coder) in my respective init (coder) and encodeWithCode(coder) methods, but it seems only my custom properties are getting saved & restored, and the "super" properties -- such as the image itself -- are getting ignored. – sh37211 Aug 24 '15 at 00:05
  • Actually, this problem only seems to be the case when the images are stored as "Assets". I can sub-class UIImageView and, e.g., if I grab cat pictures off the internet everything works fine -- i.e. and the "super" properties (such as the image) get handled properly and are recovered -- but if I try to use one of my own 'app images' for the project, then I get nothing. I'm going to go ahead and mark this question as answered, as it seems I'm now dealing with a different problem. Thanks narohi! – sh37211 Aug 24 '15 at 02:27