Using Hive instead of SharedPreferences for storing preferences
It might not seem like an intuitive choice, but there are a couple of good reasons why you might consider using hive over shared_preferences for storing UserDefaults / Preferences:
Why
- Performance
Hive is overall faster. There is a good benchmark comparing these two and while the performance of read operation is nearly the same:
there is a huge gap between times of write and delete operations:
Note that the units here are in milliseconds and even when I ran the benchmark for the write operation with 20 entries, time of Hive was ~40ms and time of SharedPreferences was ~160 ms.
Some people may say that the difference is too small for your users to notice, which for many apps is a fair thing to say, but I would argue that it’s better to use something that scales well and stay safe as we keep adding more preferences in our app.
Because when we add dozens of small optimisations like this, all these milliseconds will sum up and it will start being noticeable by our users.
- Types supported
Hive not only supports all types that shared_preferences support -bool
,int
,double
,String
,List<String>
but alsoDateTime
,Uint8List
and actuallyList
andMap
of any primitive types. - Encryption
If you would need to encrypt some values of your preferences Hive got you covered with AES-256 encryption built-in. You can read more about it here. - Verbosity
After all, Hive is a solid database library offering various features, so we might use it for data storage as well.
In which case we end up depending just on hive instead of hive and shared_preferences.
How
Firstly we need to set up Hive in our project. If you already have done this, then you can skip to step 4:
- Add hive and hive_flutter in pubspec.yaml:
2. Add initFlutter()
call in main.dart:
3. Optional step: Add Hive.close()
in your main app class:
4. Preferences Implementation:
and that’s it. Now we can use Hive Preferences similarly as we used the shared_preferences plugin.
I like keeping my preferences keys private and exposing just concrete getters and setters, but alternatively, you could make getValue
and setValue
public and use it for everything.
Also, note that the Preferences
instance doesn’t have to be a singleton nor does it have to be synchronised - we just want to make sure that box is open before we try accessing it.
Alternatively, if we wanted same API as shared_preferences has, then we could pre-open box, which could be more convenient because all getters would be synchronous, but we would have to have “async factory” which is not necessarily cleaner:
I personally prefer the first implementation, but the choice is yours.
Additional resources
- If you would like to see a complete working app I shared sample Hive Preferences app here
- Hive’s official documentation
- Reso Coder’s Hive tutorial