Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Archive functionality to BW::Persistence #389

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

dv
Copy link
Contributor

@dv dv commented Jun 17, 2014

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.

@clayallsopp
Copy link
Contributor

This is definitely cool, thanks for submitting the PR! I'll leave it open to @markrickert and @colinta's thoughts

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.

One solution to this could be key-mangling:

BW::Persistence[:my_object] = my_object
# internally Persistence checks if my_object can be serialized (is NSCoding compliant etc)
# if so, save the key as :__archive__my_object

my_object = BW::Persistence[:my_object]
# check if :__archive__my_object exists and return, serializing if appropriate

Not sure if that's what we actually want, but it seems possible.

@markrickert
Copy link
Collaborator

@dv Could you add some documentation for this? Sorry its taken so long for me to get to this, but its definitely a cool feature!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants