--- 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
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up