编码通用String对象给出nil Swift

Gle*_*enn 0 generics ios swift codable

我有一个UserDefaults用于处理存储,删除和获取存储对象到默认值的类。我相信,这是完整的课程,简洁明了:

现在的问题在于存储功能。我似乎无法编码Encodable String对象。我知道我可以将对象存储为默认值,但这会破坏MVDefaults处理通用对象的目的。

我在这里想念什么吗?

import Foundation

enum MVDefaultsKey: String {
    case requestToken = "defaultsRequestToken"
}

/// The class that has multiple class functions for handling defaults.
/// Also has the helper class functions for handling auth tokens.
class MVDefaults {

    // MARK: - Functions

    /// Stores token.
    class func store<T: Encodable>(_ object: T, key: MVDefaultsKey) {
        let encoder = JSONEncoder()
        let encoded = try? encoder.encode(object)
        UserDefaults.standard.set(encoded, forKey: key.rawValue)
    }

    /// Removes the stored token
    class func removeDefaultsWithKey(_ key: MVDefaultsKey) {
        UserDefaults.standard.removeObject(forKey: key.rawValue)
    }

    /// Returns stored token (optional) if any.
    class func getObjectWithKey<T: Decodable>(_ key: MVDefaultsKey, type: T.Type) -> T? {
        guard let savedData = UserDefaults.standard.data(forKey: key.rawValue) else {
            return nil
        }

        let object = try? JSONDecoder().decode(type, from: savedData)

        return object
    }
}
Run Code Online (Sandbox Code Playgroud)

Swe*_*per 5

考虑一下将"hello"编码为JSON 的字符串的样子。它看起来像:

"hello"
Run Code Online (Sandbox Code Playgroud)

不是吗

那不是有效的JSON(根据here)!您不能直接将字符串编码为JSON,也不能直接解码字符串。

例如,此代码

let string = try! JSONDecoder().decode(String.self, from: "\"hello\"".data(using: .utf8)!)
Run Code Online (Sandbox Code Playgroud)

会产生错误

JSON文本不是以数组或对象开头,并且没有允许片段设置的选项。

let data = try! JSONEncoder().encode("Hello")
Run Code Online (Sandbox Code Playgroud)

会产生错误:

顶级字符串编码为字符串JSON片段。

此处的解决方法只是使用所set提供的专用方法存储您的字符串UserDefaults。不过,您仍然可以使用通用方法,只需检查类型并进行强制转换:

if let str = object as? String {
    UserDefaults.standard.set(str, forKey: key)
} else if let int = object as? Int {
    ...
Run Code Online (Sandbox Code Playgroud)