---
title: Swift 4 中 JSONEncoder 不能 encode primitive value,但 swift 5 可以
tags: iOS, swift
description: 2019/10/20
---
# Swift 4 中 JSONEncoder 不能 encode primitive value,但 swift 5 可以
聽完10/8[拐子在 iOS Taipei 的分享](https://github.com/andrew54068/keynotes/blob/master/UserDefault%3CT%3E%2BPropertyWrapper.key?fbclid=IwAR39TEKiPDT-y-GWRHkG6Mi7u_ykvjwREm7FbrmWuMUBshzx-6uH9gt0kF8)後,回家試一下他的寫法,發現跑不過。
```
protocol HasDefaultValue {
associatedtype Primitive
static var defaultValue: Primitive { get }
}
protocol DefaultValueIsSelf: HasDefaultValue where Primitive == Self { }
extension String: DefaultValueIsSelf {
typealias Primitive = String
static var defaultValue = "default nil"
}
struct Storable<Model> where Model: Codable & DefaultValueIsSelf {
private let key: String
private let store = UserDefaults.standard
init(key value: String) {
self.key = value
}
var value: Model {
get {
if let encodedData = store.value(forKey: key) as? Data,
let model: Model = try? JSONDecoder().decode(Model.self, from: encodedData) {
return model
} else {
return Model.defaultValue
}
}
set {
if let encodedData: Data = try? JSONEncoder().encode(newValue) {
store.set(encodedData, forKey: key)
} else {
assertionFailure("Data can't be encoded.")
}
}
}
}
enum Persistence {
static var storedString: Storable<String> = Storable(key: "PM = popo maker")
}
Persistence.storedString.value = "blablaaa"
print(Persistence.storedString.value)
```

## 原因
Swift 4 中 JSONEncoder 不能 encode primitive value
The top-level (root) JSON object can only be an array or dictionary
## 解法
在 Xcode 11.1 的 Playground 就 run 成功了
(跑不過是在 Xcode 10.2.1)
### Reference
https://stackoverflow.com/questions/49668246/swift-4-jsonencoder-can-not-encode-string-or-int-but-they-followed-codable-prot?rq=1
https://stackoverflow.com/questions/50257242/jsonencoder-wont-allow-type-encoded-to-primitive-value
https://bugs.swift.org/browse/SR-6163