Dekoter 0.3.0

Dekoter 0.3.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2017年6月
SwiftSwift 版本3.0
SPM支持 SPM

Artem Stepanenko 维护。



Dekoter 0.3.0

  • Artem Stepanenko

Dekoter

为什么您可能会感兴趣

填补了 Swift 结构体缺少 NSCoding 支持的空白。如果您曾经实现过 NSCodingKoting 对您来说也将是熟悉的。

感觉有多熟悉

让我们快速回顾一下如何实现 NSCoding

class Cat: NSObject, NSCoding {

    let name: String

    init(name: String) {
        self.name = name
    }

    // MARK: - NSCoding

    private struct Key {
        static let name = "name"
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(name, forKey: Key.name)
    }

    required convenience init?(coder aDecoder: NSCoder) {
        guard let name = aDecoder.decodeObject(forKey: Key.name) as? String else {
            return nil
        }
        self.init(name: name)
    }
}

让我们将其与 Koting 进行比较

struct Cat: Koting {

    let name: String

    // MARK: - Koting

    private struct Key {
        static let name = "name"
    }

    init?(koter: Koter) {
        guard let name: String = koter.dekotObject(forKey: Key.name) else {
            return nil
        }
        self.init(name: name)
    }

    func enkot(with koter: Koter) {
        koter.enkotObject(name, forKey: Key.name)
    }
}

因此,除了命名之外,几乎没有区别。

总结一下

  • Koting 协议添加到类声明中。
  • 实现 init?(koter:)func enkot(with:)
  • 完成!

完成后,编译器会感到满意,您可以将对象转换为 Data 并将其转换回来。

let puss = Cat(name: "Puss")
let data = NSKeyedArchiver.de_archivedData(withRootObject: puss)
guard let againPuss: Cat = NSKeyedUnarchiver.de_unarchiveObject(with: data) else { return }

另一个例子

这个例子将展示 Dekoter 的大多数功能。

struct Cat {

    enum Sex: Int {
        case male
        case female
    }

    let name: String
    let surname: String?
    let sex: Sex
    let nationality: String
    let birthPlace: Place?

    // MARK: - Koting

    private struct Key {
        static let name = "name"
        static let surname = "surname"
        static let sex = "sex"
        static let nationality = "nationality"
        static let birthPlace = "birthPlace"
    }

    init?(koter: Koter) {
        guard let name: String = koter.dekotObject(forKey: Key.name),
            let nationality: String = koter.dekotObject(forKey: Key.nationality),
            let sexValue: Int = koter.dekotObject(forKey: Key.sex),
            let sex = Sex(rawValue: sexValue) else {

            return nil
        }
        let surname: String? = koter.dekotObject(forKey: Key.surname)
        let birthPlace: Place? = koter.dekotObject(forKey: Key.birthPlace)
        self.init(name: name, surname: surname, sex: sex, nationality: nationality, birthPlace: birthPlace)
    }

    func enkot(with koter: Koter) {
        koter.enkotObject(name, forKey: Key.name)
        koter.enkotObject(surname, forKey: Key.surname)
        koter.enkotObject(sex.rawValue, forKey: Key.sex)
        koter.enkotObject(nationality, forKey: Key.nationality)
        koter.enkotObject(birthPlace, forKey: Key.birthPlace)
    }
}

我们从中学到了什么

  • 拥有可选属性是可以的。

如您所见,这里有两个可选属性。要编码它们,您不需要做任何特殊的事情,enkotObject(_, forKey:) 将可选作为第一个参数。对于解码,您使用 dekotObject(forKey:),它也返回可选,是否解除包装取决于您。

  • Koter 支持与 NSCoding 相同的参数类型,并且还支持实现 Koting 的类型。

在上面的例子中,Cat 有一个可选的 birthPlace 属性,其类型为 Place

  • 只有一个编码方法和一个解码方法。

无论类型如何,您都使用相同的方法:使用 enkotObject(_, forKey:) 进行编码和 dekotObject(forKey:) 进行解码。这些方法是泛型的,它们根据期望的返回值推导出类型,因此您总是应该显式指定它。

功能

将对象保存到 UserDefaults

UserDefaults扩展中实现了两种方法:de_set(_, forKey:)de_object(forKey:)

let murzik = Cat(name: "Murzik", surname: nil, sex: .male, nationality: "GER", birthPlace: nil)
userDefaults.de_set(murzik, forKey: "cat")
let againMurzik: Cat? = userDefaults.de_object(forKey: "cat")

并且

let sonya = Cat(name: "Sonya", surname: "Kryvonis", sex: .female, nationality: "UA", birthPlace: Place(country: "Ukraine", city: "Lviv"))
let puff: Cat = Cat(name: "Puff", surname: nil, sex: .female, nationality: "US", birthPlace: nil)
let cats = [ sonya, puff ]
userDefaults.de_set(cats, forKey: Key.cat)
guard let againCats: [Cat] = userDefaults.de_object(forKey: Key.cat) else { return }

存档和解档对象

该库包含两个针对NSKeyedArchiverNSKeyedUnarchiver的扩展,为实现了Koting协议的对象提供方法。

let emma = Cat(name: "Emma", surname: "Lambert", sex: .female, nationality: "FR", birthPlace: Place(country: "France", city: "Marseille"))
let data = NSKeyedArchiver.de_archivedData(withRootObject: emma)        
guard let againEmma: Cat = NSKeyedUnarchiver.de_unarchiveObject(with: data) else { return }

并且

let sonya = Cat(name: "Sonya", surname: "Kryvonis", sex: .female, nationality: "UA", birthPlace: Place(country: "Ukraine", city: "Lviv"))
let puff: Cat = Cat(name: "Puff", surname: nil, sex: .female, nationality: "US", birthPlace: nil)
let cats = [ sonya, puff ]
let data = NSKeyedArchiver.de_archivedData(withRootObject: cats)
guard let againCats: [Cat] = NSKeyedUnarchiver.de_unarchiveObject(with: data) else { return }

JSON

一个JSONSerialization扩展使从JSON反序列化变得非常简单。

let oneCat: Cat? = JSONSerialization.de_jsonObject(with: oneCatData)
let cats: [Cat]? = JSONSerialization.de_jsonObject(with: catsData)

对于只使用此功能的结构体,不需要实现Koting协议(包含2个方法),而是实现一个Dekoting协议(只有一个方法)。

微任务

尽管任务规模不大,但这个库对自己的使命感到自豪。它愿意像NSCoding一样,为开发者提供优质服务。开发者不应该在没有方便的工具将Swift结构体转换成Data及其返回时感到迷茫和失望。

为什么是Dekoter

你可能会在各地看到一些猫。这有其原因。“Kot”在某些斯拉夫语中意为“猫”,听起来和“code”很相似。

“enkot” -> “encode”

“dekot” -> “decode”

“koter” -> “coder”

“koting” -> “coding”

“dekoter” -> “decoder”

合作

亲爱的朋友们,我们非常欢迎您的帮助!支持这个项目有多种方式。

  • 创建一个问题。

如果您发现了一个问题,或者您知道如何改进,或者您有问题。

  • 创建一个拉取请求。

如果您开发了一些重要内容(以前作为问题提交)。

  • 给我发一封电子邮件。

如果您想分享您在使用这个库时的正面或负面的体验,但又难以以问题表单的形式表达。或者,也许,您不愿意让它公开可用。

我总是很高兴收到您的邮件。

许可

该库可用在MIT许可下。更多详情请参阅LICENSE文件。