You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A Swift package for encoding to- and decoding from **JSON API** compliant requests and responses.
5
5
@@ -320,11 +320,18 @@ A resource object that does not have attributes can be described by adding the f
320
320
typealiasAttributes= NoAttributes
321
321
```
322
322
323
-
`Attributes` can be accessed via the `subscript` operator of the `ResourceObject` type as follows:
323
+
As of Swift 5.1, `Attributes` can be accessed via dynamic member keypath lookup as follows:
324
+
```swift
325
+
let favoriteColor: String= person.favoriteColor
326
+
```
327
+
328
+
🗒 `Attributes` can also be accessed via the older `subscript` operator as follows:
324
329
```swift
325
330
let favoriteColor: String= person[\.favoriteColor]
326
331
```
327
332
333
+
In both cases you retain type-safety, although neither plays particularly nicely with code autocompletion. It is best practice to pick an attribute access syntax and stick with it. At some point in the future the syntax deemed less desirable may be deprecated.
334
+
328
335
#### `Transformer`
329
336
330
337
Sometimes you need to use a type that does not encode or decode itself in the way you need to represent it as a serialized JSON object. For example, the Swift `Foundation` type `Date` can encode/decode itself to `Double` out of the box, but you might want to represent dates as ISO 8601 compliant `String`s instead. The Foundation library `JSONDecoder` has a setting to make this adjustment, but for the sake of an example, you could create a `Transformer`.
@@ -363,15 +370,15 @@ You can also creator `Validators` and `ValidatedAttribute`s. A `Validator` is ju
363
370
364
371
#### Computed `Attribute`
365
372
366
-
You can add computed properties to your `ResourceObjectDescription.Attributes` struct if you would like to expose attributes that are not explicitly represented by the JSON. These computed properties do not have to be wrapped in `Attribute`, `ValidatedAttribute`, or `TransformedAttribute`. This allows computed attributes to be of types that are not `Codable`. Here's an example of how you might take the `person[\.name]` attribute from the example above and create a `fullName` computed property.
373
+
You can add computed properties to your `ResourceObjectDescription.Attributes` struct if you would like to expose attributes that are not explicitly represented by the JSON. These computed properties do not have to be wrapped in `Attribute`, `ValidatedAttribute`, or `TransformedAttribute`. This allows computed attributes to be of types that are not `Codable`. Here's an example of how you might take the `person.name` attribute from the example above and create a `fullName` computed property.
367
374
368
375
```swift
369
376
publicvar fullName: Attribute<String> {
370
377
return name.map { $0.joined(separator: "") }
371
378
}
372
379
```
373
380
374
-
If your computed property is wrapped in a `AttributeType` then you can still use the default subscript operator to access it (as would be the case with the `person[\.fullName]` example above). However, if you add a property to the `Attributes``struct` that is not wrapped in an `AttributeType`, you must either access it from its full path (`person.attributes.newThing`) or with the "direct" subscript accessor (`person[direct: \.newThing]`). This keeps the subscript access unambiguous enough for the compiler to be helpful prior to explicitly casting, comparing, or storing the result.
381
+
If your computed property is wrapped in a `AttributeType` then you can still use the default subscript operator to access it (as would be the case with the `person.fullName` example above). However, if you add a property to the `Attributes``struct` that is not wrapped in an `AttributeType`, you must either access it from its full path (`person.attributes.newThing`) or with the "direct" subscript accessor (`person[direct: \.newThing]`). This keeps the subscript access unambiguous enough for the compiler to be helpful prior to explicitly casting, comparing, or storing the result.
375
382
376
383
### Copying/Mutating `ResourceObjects`
377
384
`ResourceObject` is a value type, so copying is its default behavior. There are two common mutations you might want to make when copying a `ResourceObject`:
@@ -633,7 +640,7 @@ typealias User = JSONAPI.ResourceObject<UserDescription, NoMetadata, NoLinks, St
633
640
Given a value `user` of the above resource object type, you can access the `createdAt` attribute just like you would any other:
634
641
635
642
```swift
636
-
let createdAt = user[\.createdAt]
643
+
let createdAt = user.createdAt
637
644
```
638
645
639
646
This works because `createdAt` is defined in the form: `var {name}: ({ResourceObject}) -> {Value}` where `{ResourceObject}` is the `JSONAPI.ResourceObject` described by the `ResourceObjectDescription` containing the meta-attribute.
0 commit comments