Skip to content

Commit 1798c04

Browse files
Abdul Mateen R Iharrytmthy
authored andcommitted
refactor: Undeprecate SafeBox.create(), document correct usage, and warn against misuses
1 parent 00a6850 commit 1798c04

File tree

2 files changed

+63
-12
lines changed

2 files changed

+63
-12
lines changed

README.md

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,67 @@ dependencies {
8787

8888
## Basic Usage
8989

90+
First, provide SafeBox as a singleton:
91+
92+
```kotlin
93+
@Singleton
94+
@Provides
95+
fun provideEncryptedSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
96+
SafeBox.create(context, PREF_FILE_NAME) // Replacing EncryptedSharedPreferences
97+
```
98+
99+
Or use the built-in singleton helper:
100+
90101
```kotlin
91-
val safeBox = SafeBox.create(context, fileName = "secure-prefs")
102+
SafeBoxProvider.init(context, PREF_FILE_NAME)
103+
val prefs = SafeBoxProvider.get()
104+
```
92105

93-
safeBox.edit()
106+
Then use it like any `SharedPreferences`:
107+
108+
```kotlin
109+
prefs.edit()
94110
.putInt("userId", 123)
95111
.putString("name", "Luna Moonlight")
96112
.apply()
97113

98-
val userId = safeBox.getInt("userId", -1)
99-
val email = safeBox.getString("email", null)
114+
val userId = prefs.getInt("userId", -1)
115+
val email = prefs.getString("email", null)
116+
```
117+
118+
### Anti-Patterns
119+
120+
#### ❌ Do NOT create multiple SafeBox instances with the same file name
121+
122+
```kotlin
123+
class HomeViewModel @Inject constructor() : ViewModel() {
124+
125+
private val safeBox = SafeBox.create(context, PREF_FILE_NAME) // ❌ New instance per ViewModel
126+
}
127+
```
128+
129+
This may cause FileChannel conflicts, memory leaks, or stale reads across instances.
130+
131+
---
132+
133+
#### ⚠️ Avoid scoping SafeBox to short-lived components
134+
135+
```kotlin
136+
@Module
137+
@InstallIn(ViewModelComponent::class) // ⚠️ New instance per ViewModel
138+
object SomeModule {
139+
140+
@Provides
141+
fun provideSafeBox(@ApplicationContext context: Context): SafeBox =
142+
SafeBox.create(context, PREF_FILE_NAME)
143+
}
144+
145+
class HomeViewModel @Inject constructor(private val safeBox: SafeBox) : ViewModel() {
146+
147+
override fun onCleared() {
148+
safeBox.close() // Technically safe, but why re-create SafeBox for every ViewModel?
149+
}
150+
}
100151
```
101152

102153
## Migrating from EncryptedSharedPreferences

safebox/src/main/java/com/harrytmthy/safebox/SafeBox.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,10 @@ public class SafeBox private constructor(
317317
*
318318
* This method handles secure initialization and is recommended for most use cases.
319319
*
320+
* **Common pitfalls:**
321+
* - Do NOT create multiple SafeBox instances with the same file name.
322+
* - Avoid scoping SafeBox to short-lived components (e.g. ViewModel).
323+
*
320324
* @param context The application context
321325
* @param fileName The name of the backing file used for persistence
322326
* @param keyAlias The identifier for storing the key (used to locate its encrypted form)
@@ -328,10 +332,6 @@ public class SafeBox private constructor(
328332
*/
329333
@JvmOverloads
330334
@JvmStatic
331-
@Deprecated(
332-
message = "Use SafeBoxProvider.init(...) and SafeBoxProvider.get() instead.",
333-
replaceWith = ReplaceWith("SafeBoxProvider.get()"),
334-
)
335335
public fun create(
336336
context: Context,
337337
fileName: String,
@@ -362,6 +362,10 @@ public class SafeBox private constructor(
362362
* This is useful for testing or advanced use cases where you want to control
363363
* the encryption mechanism directly.
364364
*
365+
* **Common pitfalls:**
366+
* - Do NOT create multiple SafeBox instances with the same file name.
367+
* - Avoid scoping SafeBox to short-lived components (e.g. ViewModel).
368+
*
365369
* @param context The application context
366370
* @param fileName The name of the backing file used for persistence
367371
* @param keyCipherProvider Cipher used for encrypting and decrypting keys
@@ -372,10 +376,6 @@ public class SafeBox private constructor(
372376
*/
373377
@JvmOverloads
374378
@JvmStatic
375-
@Deprecated(
376-
message = "Use SafeBoxProvider.init(...) and SafeBoxProvider.get() instead.",
377-
replaceWith = ReplaceWith("SafeBoxProvider.get()"),
378-
)
379379
public fun create(
380380
context: Context,
381381
fileName: String,

0 commit comments

Comments
 (0)