封装 3.0.0

封装 3.0.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最新发布2017年11月
SwiftSwift 版本4.0
SPM支持 SPM

John Sundell 维护。



封装 3.0.0

Unbox | 封装

封装是一个容易使用的 Swift JSON 编码器。不要花费数小时编写 JSON 编码代码 - 直接封装就可以了!

使用封装与调用 wrap() 操作你希望编码的任何 classstruct 实例相同简单。它会自动编码你类型的所有属性,包括嵌套对象、集合、枚举等!

它还提供了一组简单但强大的自定义 API,让您能够轻松地在任何模型设置中使用它。

基本示例

假设你有一个常用的 User 模型

struct User {
    let name: String
    let age: Int
}

let user = User(name: "John", age: 28)

使用 wrap(),你现在可以用一条命令来编码 User 实例

let dictionary: [String : Any] = try wrap(user)

这将生成以下 Dictionary

{
    "name": "John",
    "age": 28
}

高级示例

前面的例子很简单,但封装可以为您编码最复杂的结构,包括可选的、非可选的和自定义类型值,而无需您额外编写任何代码。假设我们有一个以下模型设置

struct SpaceShip {
    let type: SpaceShipType
    let weight: Double
    let engine: Engine
    let passengers: [Astronaut]
    let launchLiveStreamURL: URL?
    let lastPilot: Astronaut?
}

enum SpaceShipType: Int, WrappableEnum {
    case Apollo
    case Sputnik
}

struct Engine {
    let manufacturer: String
    let fuelConsumption: Float
}

struct Astronaut {
    let name: String
}

让我们创建一个 SpaceShip 实例

let ship = SpaceShip(
    type: .Apollo,
    weight: 3999.72,
    engine: Engine(
        manufacturer: "The Space Company",
        fuelConsumption: 17.2321
    ),
    passengers: [
        Astronaut(name: "Mike"),
        Astronaut(name: "Amanda")
    ],
    launchLiveStreamURL: URL(string: "http://livestream.com"),
    lastPilot: nil
)

现在让我们用一个 wrap() 调用来编码它

let dictionary: WrappedDictionary = try wrap(ship)

这将生成以下字典

{
    "type": 0,
    "weight": 3999.72,
    "engine": {
        "manufacturer": "The Space Company",
        "fuelConsumption": 17.2321
    },
    "passengers": [
        {"name": "Mike"},
        {"name": "Amanda"}
    ],
    "launchLiveStreamURL": "http://livestream.com"
}

如你所见,封装自动编码了 URL 属性为它的 absoluteString,并忽略了任何 nil 属性(减少了生成的 JSON 的大小)。

自定义

尽管自动化很棒,但定制同样重要。幸运的是,封装提供了几个覆盖点,让您可以轻松地调整其默认行为。

自定义键

默认情况下,封装使用类型的属性名作为其编码键,但有时这并不是你想要的。你可以选择通过使其符合 WrapCustomizable 并实现 keyForWrapping(propertyNamed:),来自定义一个类型的所有编码键,如下所示

struct Book: WrapCustomizable {
    let title: String
    let authorName: String

    func keyForWrapping(propertyNamed propertyName: String) -> String? {
        if propertyName == "authorName" {
            return "author_name"
        }

        return propertyName
    }
}

你还可以通过在这个方法中返回 nil 来使用 keyForWrapping(propertyNamed:) API 完全跳过一个属性。

自定义键类型

您可能有嵌套的字典,它们的键不是字符串,对于这些字典,Wrap提供了WrappableKey协议。这使您能够轻松地将任何类型转换为可以作为JSON键使用的字符串。

将键编码为snake_case

如果想要Wrap生成的字典具有snake_cased键而不是默认值(默认值是匹配已编码属性的名称),可以通过遵守WrapCustomizable并从wrapKeyStyle属性返回.convertToSnakeCase轻松实现。这样做会将属性名myProperty转换为键my_property,例如。

自定义包装

对于某些嵌套类型,您可能希望自行处理包装。这特别适用于任何自定义集合或编码时具有完全不同表示的类型的类型。要做到这一点,类型需要遵守WrapCustomizable并实现wrap(context:dateFormatter:),如下所示。

struct Library: WrapCustomizable {
    private let booksByID: [String : Book]

    func wrap(context: Any?, dateFormatter: DateFormatter?) -> Any? {
        return Wrapper(context: context, dateFormatter: dateFormatter).wrap(self.booksByID)
    }
}

枚举支持

Wrap还使得轻松编码您的类型所使用的任何enum值变得容易。如果一个enum基于原始类型(如StringInt),您所需要做的只是声明符合WrappableEnum,其余的都将为您处理。

非原始类型的enum值也会自动编码。默认行为是将任何没有相关值的值编码为其字符串表示,并将具有相关值的值编码为字典(字符串表示是键),如下所示。

enum Profession {
    case developer(favoriteLanguageName: String)
    case lawyer
}

struct Person {
    let profession = Profession.developer(favoriteLanguageName: "Swift")
    let hobbyProfession = Profession.lawyer
}

编码为

{
    "profession": {
        "developer": "Swift"
    },
    "hobbyProfession": "lawyer"
}

上下文对象

为了能够轻松编码在编码过程中可能会用到任何依赖,Wrap提供在启动包装过程时提供上下文对象的能力(通过调用wrap(object, context: myContext)。

上下文可以是Any类型,并且可以在所有WrapCustomizable包装方法中访问。以下是一个示例,其中我们向Booktitle添加了一个前缀。

struct Book: WrapCustomizable {
    let title: String

    func wrap(context: Any?, dateFormatter: DateFormatter?) -> Any? {
        guard let prefix = context as? String else {
            return nil
        }

        return [
            "title" : prefix + self.title
        ]
    }
}

兼容性

Wrap支持以下平台

  • iOS 8+
  • macOS 10.9+
  • watchOS 2+
  • tvOS 9+
  • Linux

Wrap的当前版本(以及master分支)仅与Swift 3和Xcode 8兼容,但是有一个可以使用Swift 2.3的swift2分支

安装

CocoaPods

将行pod "Wrap"添加到您的Podfile

Carthage

将行github "johnsundell/wrap"添加到您的Cartfile

手动

克隆仓库并将文件Wrap.swift拖到Xcode项目中。

Swift Package Manager

将行.Package(url: "https://github.com/JohnSundell/Wrap.git", majorVersion: 2)添加到您的Package.swift文件中。

希望您喜欢包装您的对象!

有关Wrap和其他开源项目的更多信息,请关注我的Twitter:@johnsundell

此外,请确保查看Unbox,它可让您轻松地对JSON进行解码。