---
# System prepended metadata

title: Swift 4 中 JSONEncoder 不能 encode primitive value，但 swift 5 可以
tags: [' swift', iOS]

---

---
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)

```


![](https://i.imgur.com/IGjPlad.png)


## 原因 

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