Skip to content
This repository has been archived by the owner on Mar 16, 2021. It is now read-only.

save Set<String> Is someone using this? -> YES PLEASE! #7

Open
enkemari opened this issue May 4, 2015 · 12 comments
Open

save Set<String> Is someone using this? -> YES PLEASE! #7

enkemari opened this issue May 4, 2015 · 12 comments

Comments

@enkemari
Copy link

enkemari commented May 4, 2015

Hi,

In the "Missing Features" section you ask if someone wants to save Set - yes, I do!

Well, actually more saving a Map or an ArrayList<Map<String, Object>> - that's what I work with mostly. So I would very often need to save something like this as the value to some key:

[
   {
      "key": "value",
      "key2": 222,
      "key3": {"sub_key":"sub_value", "sub_key2":23232},
      "key4": [1,2,3,4],
      "key5": "etc"
   }
]

I've had to use a combination of Base64OutputStream, ByteArrayOutputStream and ObjectOutputStream to save objects to shared prefs. :\

@franciscerio
Copy link

up

@passsy passsy added this to the future release milestone May 4, 2015
@passsy
Copy link
Contributor

passsy commented May 4, 2015

I see the benefit of saving Lists or Sets. But I think saving complex "json" structures is out of the scope for this library.

You could easily use gson to create a string representative of your object and save it into Tray and parse it again with gson.

@ubeyou
Copy link

ubeyou commented Oct 2, 2015

up, have been using Set with SharedPreference, would like to see this feature in 1.0

@KioKrofovitch
Copy link

Upvote! I would like to be able to use a regular String Set as well

@domenukk
Copy link

I want to add it would be great to not only put and get StringSets but also to append to StringSets atomically.
The Android SharedPrefs are missing this function afaik so right now we lock, get the current set, append something and then write the new value back. Locking is not possible in a multiprocess app. (Unless we start having a "locked" preference and listen for a value change, but then this is getting out of hand 🎯)

@eyedol
Copy link
Contributor

eyedol commented Oct 20, 2016

A simple trick like this 1 could get you to save the Set as a serialized JSON string into Tray as mentioned by @passsy

@eyedol
Copy link
Contributor

eyedol commented Oct 22, 2016

@passsy I'm wondering if this issue is still valid? I would like to work on it if you're open to extending the scope of this library. If it's going to stretch the scope a bit, I could make it a module( something like tray-converters ) on it own that could be installed as an extra dependency for users who wants to save complex object with tray. This will complement tray itself.

With the extra module approach, I could generalize it so people can use whatever serialization libraries they like; like Gson, Moshi, Jackson, etc. I would support these three with Gson being the default.

Rough sample usage will be in the form:

TrayConverter trayConverter = new TrayConverter.Builider()
     // This will override the default converter
    .setConverter(MoshiConverter())
    .build();

// To convert object to JSON string
String json = trayConverter.serialize(model);

final AppPreferences appPreferences = new AppPreferences(getContext());
appPreferences.put("key", jsonString);

// To convert JSON string back to object,
final String value = appPreferences.getString("key", null);

Model model = trayConverter.deserialize(value, Model.class);

I see people will appreciate this if tray supports saving complex object without having to do a lot of extra work. I'm judging based on the +1s on this issue. Let me know what you think.

@domenukk
Copy link

@eyedol keep one thing in mind though: if objects would be supported there should be a locking mechanism or transactions (or some async wait for lock queue) for them. Else it's pretty useless, at least for me.

@eyedol
Copy link
Contributor

eyedol commented Oct 24, 2016

@domenukk thanks for chipping in. I'm curious how you currently save objects. What I'm proposing will be independent of Tray. It just gives Tray a string value to save or expect a string value from it to parse. I don't think async, wait, or locks will be necessary in my implementation.

@domenukk
Copy link

@eyedol depends on your use case of course. If you want exactly one process (like a receiver) to save and n processes to read then this approach is fine but it opens the door for people to shoot themselves in the foot. As soon as you want to change an object you start having race conditions. For String Sets right now I use old school shared preferences and put the 'insert into' and 'get' methods in synchronized blocks. Having this option in Tray somehow would be great.
If you start messing with objects you might want to consider a proper db like realm.
That being said if you want to do it, do it.

@eyedol
Copy link
Contributor

eyedol commented Oct 26, 2016

@domenukk thanks for sharing your insight and current approach to the problem. I was of the inclination that people were interested in saving the object as a serialized JSON string( with Tray supporting strings ) hence why I proposed this approach. If it will cause more issues than good then no need. I was hoping to hear a perspective from the project maintainers but not yet. Hopefully soon.

Anyway, I made this into a standalone Java library instead. More so like a wrapper around the serializers out there. It's in the same vain as I proposed above. This way, I felt it won't mess too much with the core project.

@Cilenco
Copy link

Cilenco commented Dec 24, 2017

This would also be great for the new PreferenceDataStore class because we have to implement getStringSet. With this we can tell Preferences to use this storage implementation in the background by calling:

PreferenceManager pm = getPreferenceManager();
pm.setPreferenceDataStore(new SettingsDataStore(getContext()));

on a PreferenceFragmentCompat (here SettingsDataStore is a subclass of PreferenceDataStore).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

8 participants