Try   HackMD

Swift 4 中 JSONEncoder 不能 encode primitive value,但 swift 5 可以

聽完10/8拐子在 iOS Taipei 的分享後,回家試一下他的寫法,發現跑不過。

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)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

原因

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