Skip to main content
Version: 1.5.0

Type Registration

This page covers registration APIs for user-defined types.

Why Registration Is Required

Register user-defined structs, classes, enums, unions, and external targets before serialization or deserialization.

If a type is missing, deserialization fails with:

  • Type not registered: ...

Register by Numeric ID

Use a stable ID shared by serializer and deserializer peers.

@ForyStruct
struct User {
var name: String = ""
var age: Int32 = 0
}

let fory = Fory()
try fory.register(User.self, id: 1)

For an external structural serializer, register the separate serializer declaration:

@ForyStruct(target: ThirdParty.User.self)
struct UserSerializer {
var name: String
var age: UInt32
}

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

If an application intentionally gives an external type one retroactive Serializer conformance with Target == Self, register the target itself:

try fory.register(UUID.self, id: 2)

After registering a separate serializer, select it explicitly at each root, field, or carrier child where it is required.

Register by Name

Fully-qualified name

try fory.register(User.self, name: "com.example.User")

name is split by the last .:

  • namespace: com.example
  • type name: User

Simple names such as User use an empty namespace. Empty names and names ending in . are invalid.

Consistency Rules

Keep registration mapping consistent across peers:

  • ID mode: same type uses same numeric ID on all peers
  • Name mode: same type uses same namespace and type name on all peers
  • Do not mix ID and name mapping for the same logical type across services
  • Register only one serializer for each target type on a Fory instance

Registration closes after the first root serialization or deserialization. Complete all registrations before the first root operation.

Dynamic Types and Registration

When serializing Any, AnyObject, or application protocol values, register each concrete target through its ordinary, external structural, or custom serializer. Any and AnyObject use direct root APIs; application protocols select DynamicSerializer<T> explicitly.