跳到主要内容
版本:1.5.0

基础序列化

本页介绍 Swift 中的对象图序列化和核心 API 用法。

对象图序列化

使用 @ForyStruct@ForyEnum@ForyUnion,注册类型,然后进行序列化和反序列化。

import Foundation
import Fory

@ForyStruct
struct Address: Equatable {
var street: String = ""
var zip: Int32 = 0
}

@ForyStruct
struct Person: Equatable {
var id: Int64 = 0
var name: String = ""
var nickname: String? = nil
var tags: Set<String> = []
var scores: [Int32] = []
var addresses: [Address] = []
var metadata: [Int8: Int32?] = [:]
}

let fory = Fory()
try fory.register(Address.self, id: 100)
try fory.register(Person.self, id: 101)

let person = Person(
id: 42,
name: "Alice",
nickname: nil,
tags: ["swift", "xlang"],
scores: [10, 20, 30],
addresses: [Address(street: "Main", zip: 94107)],
metadata: [1: 100, 2: nil]
)

let data = try fory.serialize(person)
let decoded: Person = try fory.deserialize(data)
assert(decoded == person)

与已有缓冲区配合使用

你可以把序列化结果追加到现有 Data,也可以从 ByteBuffer 反序列化。

var output = Data()
try fory.serialize(person, to: &output)

let inputBuffer = ByteBuffer(data: output)
let fromBuffer: Person = try fory.deserialize(from: inputBuffer)
assert(fromBuffer == person)

选择序列化器

实现 Serializer 且满足 Target == Self 的类型会选择自身作为序列化器:

let data = try fory.serialize(person)
let decoded: Person = try fory.deserialize(data)

这种隐式选择可以穿过生成字段以及普通可选值、数组、集合和字典进行组合。应用有意为外部类型添加 Target == Self 的追溯遵循时,同样适用。

当使用单独定义的序列化器处理目标值时,通过 with 选择它:

try fory.register(UserSerializer.self, id: 200)

let data = try fory.serialize(
externalUser,
with: UserSerializer.self
)
let decoded = try fory.deserialize(
data,
with: UserSerializer.self
)

相同的选择方式也适用于已有缓冲区:

var output = Data()
try fory.serialize(
externalUser,
with: UserSerializer.self,
to: &output
)

let input = ByteBuffer(data: output)
let decoded = try fory.deserialize(
from: input,
with: UserSerializer.self
)

有关结构化序列化器和递归组合的根值容器,请参阅外部类型序列化。有关由类型自身实现的序列化器、追溯遵循和单独定义的自定义序列化器,请参阅自定义序列化器

内置支持的类型

基础标量类型

  • Bool
  • Int8Int16Int32Int64Int
  • UInt8UInt16UInt32UInt64UInt
  • FloatDouble
  • String
  • Data

日期与时间类型

  • Date
  • LocalDate
  • Duration

时间戳值使用 Date,仅包含日期的值使用 LocalDateLocalDate 可通过 fromEpochDay(_:)toEpochDay()init(utcDate:)toUTCDate() 在纪元日与 Date 之间转换。

集合类型

  • 值直接实现 Serializer 的可选值和数组
  • 元素直接实现 Serializer 且遵循 Hashable 的集合
  • 键和值直接实现 Serializer,且键遵循 Hashable 的字典

使用单独定义的序列化器处理子项时,通过以下类型进行组合:

  • OptionalSerializer<S>
  • ArraySerializer<S>
  • SetSerializer<S>
  • DictionarySerializer<KS, VS>

动态类型

  • AnyAnyObject
  • AnyHashable
  • 任意应用协议值
  • 支持的异构数组和字典

AnyAnyObject 为根值时使用直接的根值 API。以任意应用协议值为根值时,以及动态值嵌套在容器中时,通过 with: 显式选择序列化器。详见多态与动态类型