Skip to content

Commit dd4989d

Browse files
committed
Add blogpost on array backwards compatibility using property wrappers
1 parent 2272e58 commit dd4989d

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
---
2+
layout: post
3+
author: matt
4+
title: "Array backwards compatibility using Property Wrappers"
5+
date: 2020-07-07 14:19:05 +0200
6+
comments: true
7+
categories:
8+
---
9+
10+
Let's assume that you're doing an application which shows your users pretty pictures of seasons. You contact your backend folks and they tell you that the world is simple, there are only three seasons:
11+
12+
```swift
13+
enum Season: String, Decodable {
14+
case spring, summer, autumn
15+
}
16+
```
17+
<!--more-->
18+
19+
In order to compose things nicely, you put the seasons into a struct:
20+
21+
```swift
22+
struct Seasons: Decodable {
23+
var available: [Season]
24+
}
25+
```
26+
27+
The following JSON comes from the server, it gets decoded, everything works well:
28+
```json
29+
"available": ["spring", "summer", "autumn"]
30+
// [__lldb_expr_12.Season.spring, __lldb_expr_12.Season.summer, __lldb_expr_12.Season.autumn]
31+
```
32+
33+
The application gets released. Time passes, winter comes and the app gets updated available seasons from the backend:
34+
```json
35+
"available": ["spring", "summer", "autumn", "winter"]
36+
```
37+
38+
What happens now? Your functionality breaks.
39+
Since the app can't understand `Season.winter`, no seasons get decoded. You receive a lot of bug reports, and your users are not happy ☹️
40+
41+
If only there was something we could do to prevent this from happening..
42+
This seems like a nice use case for property wrappers!
43+
44+
```swift
45+
@propertyWrapper
46+
struct IgnoreUnknown<Value: Decodable>: Decodable {
47+
var wrappedValue: [Value]
48+
49+
private struct Empty: Decodable {}
50+
51+
init(from decoder: Decoder) throws {
52+
var container = try decoder.unkeyedContainer()
53+
self.wrappedValue = []
54+
while !container.isAtEnd {
55+
do {
56+
wrappedValue.append(try container.decode(Value.self))
57+
} catch {
58+
_ = try? container.decode(Empty.self)
59+
}
60+
}
61+
}
62+
}
63+
```
64+
65+
This way, we simply add `@IgnoreUnknown` before our available seasons and voilà! After that, the `available` array simply skips the values it cannot understand 🚀
66+
```swift
67+
struct Seasons: Decodable {
68+
@IgnoreUnknown
69+
var available: [Season]
70+
}
71+
```
72+
73+
Property Wrappers come with a lot of other great use cases. Please see [Properties](https://docs.swift.org/swift-book/LanguageGuide/Properties.html) in Apple documentation for more details 🙂
74+
75+
Hope this blogpost was helpful, thanks for reading!

0 commit comments

Comments
 (0)