# Files and "preferences"

> Lightweight persistence has been removed — what to use instead (SQLite kv or a file in homeFolder).

Source: https://crossfly.dev/docs/data-and-services/files-and-preferences — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Files and "preferences"

This page is **honest about a removal**. If you're looking for `SharedPreferences`/`UserDefaults`, stop:
in CrossFly that mechanism **does not exist**.

## ⚠️ Lightweight persistence has been removed
`Settings.appSettings`, `appSecretKey`, `refresh()` and the old "preferences" **no longer exist** — and
**there is no automatic write on exit**. You write **explicitly**, at the right moment.

## What to use instead
| Need to store… | Use |
|---|---|
| flags, theme, last login (key→value) | **key/value table in SQLite** ([guide](/docs/data-and-services/storage-sqlite)) |
| blobs / files | a **file** in `Device.homeFolder` |

### Key/value in SQLite (recommended for settings)
```java
try (SqliteDb db = SqliteDb.open("app.db")) {
   db.exec("CREATE TABLE IF NOT EXISTS kv(k TEXT PRIMARY KEY, v TEXT)");
   db.execute("INSERT OR REPLACE INTO kv(k, v) VALUES(?, ?)", "tema", "escuro");
   String tema = db.queryString("SELECT v FROM kv WHERE k=?", "tema");   // null if absent
}
```

### Simple file in `Device.homeFolder`
`Device.homeFolder` is the app's base directory (varies by platform):
| Platform | `homeFolder` |
|---|---|
| Desktop | working directory (cwd) |
| Android | app's private storage |
| iOS | *documents* folder |

```java
String path = Device.homeFolder + "config.json";

byte[] bytes = Utils.readBytes(path);   // ⚠️ null if the file does not exist
if (bytes != null) {
   String json = new String(bytes);
   // … parse …
}
// FileHandle (libGDX) for cases that need more control:
FileHandle fh = Utils.loadFile(path);   // null if not found
```

## Best practices
- **Write explicitly** at the right points (when saving config, when leaving a screen) — nothing is
  persisted on its own.
- Prefer **SQLite kv** over a loose file for settings (transactional, queryable).
- **Always check for `null`** from `Utils.readBytes`/`loadFile` (the file may not exist).

## Common mistakes
- Looking for `Settings.appSettings`/`SharedPreferences` — it was removed; it's not coming back.
- Assuming an automatic write on close — there is none; write it yourself.
- Not handling `null` when reading a nonexistent file.

## See also
- [Persistence with SQLite](/docs/data-and-services/storage-sqlite)
