Skip to content

Commit 5fbe5f4

Browse files
committed
Lots of README re org rewrite and cleanup
1 parent 282706a commit 5fbe5f4

File tree

1 file changed

+42
-106
lines changed

1 file changed

+42
-106
lines changed

README.md

Lines changed: 42 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -33,28 +33,7 @@ PersistentKeyValueKit is backed by a robust test suite.
3333

3434
## Usage
3535

36-
### Types
37-
38-
#### Primitive Types
39-
40-
Primitive types are natively supported by `UserDefaults` and/or `NSUbiquitousKeyValueStore`. These types are all
41-
`KeyValuePersistible` and are stored directly with no transformation (where possible). All other `KeyValuePersistible`
42-
types must be transformed into a primitive type through a `PersistentKeyValueRepresentation`.
43-
44-
The primitive types are:
45-
46-
- `Bool`
47-
- `Data`
48-
- `Double`
49-
- `Float`
50-
- `Int`
51-
- `Optional`
52-
- `String`
53-
- `URL`
54-
- `[KeyValuePersisiblt]`
55-
- `[String: any KeyValuePersisitble]`
56-
57-
#### Make a Type Persistible
36+
### Make a Type Persistible
5837

5938
Make a type persistible by conforming to `KeyValuePersistible`.
6039

@@ -64,37 +43,52 @@ Make a type persistible by conforming to `KeyValuePersistible`.
6443
static var persistentKeyValueRepresentation: some PersistentKeyValueRepresentation<Self> { get }
6544
```
6645

67-
A representation is a type that describes how a value is persisted – how is is stored inside of `UserDefaults` or
68-
`NSUbiquitousKeyValueStore`, and how it is retrieved. Severeal common representations are provided and it is easy to
46+
A representation is a type that describes how a value is persisted – how it is stored inside of `UserDefaults` or
47+
`NSUbiquitousKeyValueStore`, and how it is retrieved. Several common representations are provided and it is easy to
6948
build custom ones inside of the `KeyValuePersistible` implementation.
7049

7150
e.g.
7251

7352
```swift
7453
extension UIContentSizeCategory: KeyValuePersistible {
75-
public static var persistentKeyValueRepresentation: some PersistentKeyValueRepresentation<Self> {
54+
static var persistentKeyValueRepresentation: some PersistentKeyValueRepresentation<Self> {
7655
RawRepresentablePersistentKeyValueRepresentation()
7756
}
7857
}
7958
```
8059

81-
##### Built-in Persistence Representations
60+
#### Primitive Types
61+
62+
Primitive types are natively supported by `UserDefaults` and/or `NSUbiquitousKeyValueStore`. These types are all
63+
`KeyValuePersistible` and are stored directly with little-to-no transformation. All other `KeyValuePersistible`
64+
types must be transformed into a primitive type through a `PersistentKeyValueRepresentation`.
65+
66+
The primitive types are:
67+
68+
- `Bool`
69+
- `Data`
70+
- `Double`
71+
- `Float`
72+
- `Int`
73+
- `String`
74+
- `URL`
75+
- `Optional<T> where T: KeyValuePersistible`
76+
- `[T] where T: KeyValuePersistible`
77+
- `[String: T] where T: KeyValuePersistible`
78+
79+
### Persistence Representations
8280

8381
There are several built-in representations that cover the most common use cases for applications. They should be
8482
generic enough for almost any need. They are all described here. Their building blocks are available if necessary, but
8583
not described here.
8684

87-
###### `ProxyPersistentKeyValueRepresentation`
85+
#### `ProxyPersistentKeyValueRepresentation`
8886

8987
`ProxyPersistentKeyValueRepresentation` is a representation that persists a value as the `Proxy` type. The `Proxy` type
9088
must be a `KeyValuePersistible` type.
9189

9290
This is the base representation for types to build on top of. A common pattern is to use a primitive type as the proxy
93-
type. Any `KeyValuePersistible` type can be used as the proxy type; there is no limit to the layers of indirection.
94-
95-
> [!WARNING]
96-
> It is possible to define an infinite loop where `KeyValuePersistible` types proxy through each other recursively. This
97-
> is a programming error and will result in undefined behavior at runtime.
91+
type, but any `KeyValuePersistible` type can be used as the proxy type. There is no limit to the layers of indirection.
9892

9993
e.g.
10094

@@ -104,17 +98,17 @@ e.g.
10498
extension Date: KeyValuePersistible {
10599
public static var persistentKeyValueRepresentation: some PersistentKeyValueRepresentation<Self> {
106100
ProxyPersistentKeyValueRepresentation(
107-
to: \.timeIntervalSince1970,
108-
from: Date.init(timeIntervalSince1970:)
101+
to: \.timeIntervalSinceReferenceDate,
102+
from: Date.init(timeIntervalSinceReferenceDate:)
109103
)
110104
}
111105
}
112106
```
113107

114-
###### `RawRepresentablePersistentKeyValueRepresentation`
108+
#### `RawRepresentablePersistentKeyValueRepresentation`
115109

116-
`RawRepresentablePersistentKeyValueRepresentation` is a representation that persists a `RawRepresentable` value as its
117-
`RawValue`, if `RawValue` is `KeyValuePersistible`.
110+
`RawRepresentablePersistentKeyValueRepresentation` is a proxy representation that persists a `RawRepresentable` value as
111+
its `RawValue`, if `RawValue` is `KeyValuePersistible`.
118112

119113
e.g.
120114

@@ -134,69 +128,11 @@ extension RuntimeColorScheme: KeyValuePersistible {
134128
}
135129
```
136130

137-
###### `StringlyKeyedDictionaryPersistentKeyValueRepresentation`
138-
139-
`StringlyKeyedDictionaryPersistentKeyValueRepresentation` is a representation that persists a value as a
140-
`[String: Any]`. This is just a typealias for `ProxyPersistentKeyValueRepresentation<[String: Any]>`.
141-
142-
This representation is notable because `[String: Any]` is a primitive type and can be persisted directly with no
143-
transformation. This is the most performant way to persist keyed types; much faster than JSON coding, for example. The
144-
trade-off is that it requires manual (de)serialization.
145-
146-
> [!WARNING]
147-
> `Any` is a lie: only property list types can be stored as values. Storing an unsupported type is a programming error
148-
> and will result in a crash at runtime.
149-
150-
e.g.
151-
152-
`Address` is persisted as `[String: Any]`.
153-
154-
```swift
155-
struct Address {
156-
let street: String
157-
let city: String
158-
let state: String
159-
let zipCode: String
160-
}
161-
162-
extension Address: KeyValuePersistible {
163-
static var persistentKeyValueRepresentation: some PersistentKeyValueRepresentation<Self> {
164-
StringlyKeyedDictionaryKeyValueRepresentation {
165-
[
166-
"street": $0.street,
167-
"city": $0.city,
168-
"state": $0.state,
169-
"zipCode": $0.zipCode,
170-
]
171-
} from: {
172-
guard
173-
let street = $0["street"] as? String,
174-
let city = $0["city"] as? String,
175-
let state = $0["state"] as? String,
176-
let zipCode = $0["zipCode"] as? String
177-
else {
178-
return nil
179-
}
180-
return Address(street: street, city: city, state: state, zipCode: zipCode)
181-
}
182-
}
183-
}
184-
```
185-
186-
###### `CodablePersistentKeyValueRepresentation`
131+
#### `CodablePersistentKeyValueRepresentation`
187132

188133
`CodablePersistentKeyValueRepresentation` is a proxy representation that persists a value as the `Input`/`Output` type
189134
of the given encoder and decoder.
190135

191-
> [!TIP]
192-
> Although easy to use, `CodablePersistentKeyValueRepresentation` (with JSON) is the slowest built-in representation.
193-
> One should prefer to use any other representation when possible. If one needs to persist a small keyed type, consider
194-
> using `ProxyPersistentKeyValueRepresentation` with `[String: Any]` as the proxy type. `[String: Any]` is a primitive
195-
> type and manual (de)serialization into a dictionary will be much faster.
196-
>
197-
> If one is storing a type that is so large as to be impractical to do manual (de)serialization, reconsider using
198-
> `UserDefaults` or `NSUbiquitousKeyValueStore` altogether. They are not meant for large values.
199-
200136
e.g.
201137

202138
`Address` is persisted as `Data`.
@@ -268,9 +204,8 @@ the amount of conditional code you need to write.
268204
All key-based interfaces accept `PersistentKeyProtocol`, which both `PersistentKey` and `PersistentDebugKey` conform to.
269205

270206
> [!WARNING]
271-
> Debug keys will only work if one is compiling this framework from source (e.g. as a SwiftPM dependency). If one is
272-
> using a pre-built binary then the `DEBUG` code paths will likely not be included and default values will always be
273-
> used.
207+
> Debug keys will only work if compiling this framework from source (e.g. as a SwiftPM dependency). If using a pre-built
208+
> binary then the `DEBUG` code paths will likely not be included and default values will always be used.
274209
275210
e.g.
276211

@@ -293,12 +228,13 @@ userDefaults.get(.isAppStoreRatingEnabled) // false in Debug, true in Release
293228
#### Use a Custom Representation for a Single Key
294229

295230
Every `KeyValuePersistible` type has an associated `PersistentKeyValueRepresentation` type and
296-
`peristentKeyValueRepresentation` property. This is the default representation used to persist the value into
297-
the backing store.
231+
`peristentKeyValueRepresentation` property. This is the default representation used to persist the value with a store.
232+
233+
However, a representation for a single key can be provided at definition time—even if the value isn't
234+
`KeyValuePersistible`. This is useful for:
298235

299-
However, you can supply a different representation for a single key at definition time. This is useful if you have
300-
a type that you want to persist in a non-standard way, or if you have existing values that are stored differently
301-
from the default representation.
236+
- One-off keys for nonconforming types.
237+
- Handling older values stored differently from the default representation.
302238

303239
e.g.
304240

@@ -309,8 +245,8 @@ extension PersistentKeyProtocol where Self == PersistentKey<Date?> {
309245
"LastAppStoreReviewRequestDate",
310246
defaultValue: nil,
311247
representation: ProxyPersistentKeyValueRepresentation(
312-
to: \.timeIntervalSinceReferenceDate,
313-
from: Date.init(timeIntervalSinceReferenceDate:)
248+
to: \.timeIntervalSince1970,
249+
from: Date.init(timeIntervalSince1970:)
314250
)
315251
)
316252
}

0 commit comments

Comments
 (0)