SwiftProtoReflect is a dynamic Protocol Buffers library for Swift, enabling reflection-based message handling, serialization, and deserialization without the need for precompiled .proto files.
A Swift library for dynamic Protocol Buffers message manipulation without pre-compiled schemas.
SwiftProtoReflect enables runtime manipulation of Protocol Buffers messages without requiring code generation from .proto
files. This is useful for building generic tools, API gateways, data processors, and other applications that need to work with protobuf schemas dynamically.
Add to your Package.swift
:
dependencies: [
.package(url: "https://github.com/truewebber/swift-protoreflect.git", from: "2.0.0")
]
import SwiftProtoReflect
// Define a message schema at runtime
let personSchema = try MessageDescriptor.builder("Person")
.addField("name", number: 1, type: .string)
.addField("age", number: 2, type: .int32)
.addField("emails", number: 3, type: .string, label: .repeated)
.build()
// Create and populate a message
let message = try MessageFactory().createMessage(from: personSchema)
try message.set("name", value: "Alice")
try message.set("age", value: 25)
try message.set("emails", value: ["alice@example.com"])
// Serialize to binary or JSON
let binaryData = try BinarySerializer().serialize(message: message)
let jsonString = try JSONSerializer().serialize(message: message)
// Timestamps
let now = Date()
let timestampMessage = try now.toTimestampMessage()
let backToDate = try timestampMessage.toDate()
// JSON-like structures
let data: [String: Any] = ["user": "john", "active": true]
let structMessage = try data.toStructMessage()
// Type erasure
let anyMessage = try message.packIntoAny()
let unpackedMessage = try anyMessage.unpackFromAny(to: personSchema)
let client = ServiceClient(channel: grpcChannel)
let request = try MessageFactory().createMessage(from: requestSchema)
try request.set("query", value: "search term")
let response = try await client.unaryCall(
service: "search.SearchService",
method: "Search",
request: request
)
The library includes 43 working examples demonstrating various use cases:
git clone https://github.com/truewebber/swift-protoreflect.git
cd swift-protoreflect/examples
# Basic examples
swift run HelloWorld
swift run FieldTypes
swift run TimestampDemo
# Advanced examples
swift run DynamicGRPC
swift run ApiGateway
swift run MessageTransform
Examples are organized by topic:
SwiftProtoReflect works alongside existing Swift Protobuf code:
// Convert static to dynamic
let staticMessage = Person.with { /* ... */ }
let dynamicMessage = try staticMessage.toDynamicMessage()
// Convert dynamic to static
let staticMessage: Person = try dynamicMessage.toStaticMessage()
The library has comprehensive test coverage with 866 tests covering all functionality and edge cases.
MIT License. See LICENSE for details.