rubymotion/BubbleWrap — pull request #389 by dv (2014-06-17 09:26:25+00:00)
Title: Add Archive functionality to BW::Persistence

This PR adds the Archive module to Persistence. It simplifies storing objects that need `NSKeyArchiver`. The class of the object still needs to implement the NSCoding methods, but other than that you can simply do:

```
BW::Persistence::Archive[:my_object] = an_object
# And retrieve...
an_object = BW::Persistence::Archive[:my_object]
```

Instead of doing the NSKeyArchiver dance. This also works with Arrays and Hashes of objects, which are converted to Arrays and Hashes of archived objects respectively:

```
BW::Persistence::Archive[:my_object] = [object1, object2, 123, object4]
BW::Persistence::Archive[:some_hash] = {first: object1, second: object2, third: [object4, object5]}
```

This will recursively use NSKeyArchiver to convert all objects to NSUserDefaults-compatible types (i.e. it'll keep Strings and Numbers as Strings and Numbers, but convert any other object to NSData if they do NSCoding).

It's compatible with normal BW::Persistence (or indeed NSUserDefaults) usage. For example after the previous two lines, you could do this to retrieve the stored number:

```
BW::Persistence[:my_object][2] == 123 # true
```

The reason this cannot (probably) be implemented by default in BW::Persistence is that we don't know beforehand if the user stored NSData or an object that is archived to NSData, so we don't know whether to unarchive it or not.

We could make the convention that any NSData in BW::Persistence should be unarchived, and that you can't retrieve NSData from BW::Persistence without specifying you don't want it to be unarchived. We could also try to unarchive all NSData and only when NSKeyArchiver throws an exception return the raw NSData.

This merits a discussion.