Skip to content

SwiftProtoReflect is a dynamic Protocol Buffers library for Swift, enabling reflection-based message handling, serialization, and deserialization without the need for precompiled .proto files.

License

Notifications You must be signed in to change notification settings

truewebber/swift-protoreflect

Repository files navigation

SwiftProtoReflect

A Swift library for dynamic Protocol Buffers message manipulation without pre-compiled schemas.

Platform Swift Package Index License Coverage Ask DeepWiki

Overview

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.

Installation

Add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/truewebber/swift-protoreflect.git", from: "4.0.0")
]

⚠️ Important: We strongly recommend using version 4.0.0 or higher. Earlier versions included heavy gRPC dependencies that have been removed for a lighter, more focused library.

Basic Usage

Creating Messages Dynamically

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)

Working with Well-Known Types

// 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)

Features

  • Dynamic Message Creation: Create and manipulate protobuf messages at runtime
  • Schema Definition: Build message descriptors programmatically
  • Serialization: Binary and JSON serialization/deserialization
  • Well-Known Types: Support for Google's standard protobuf types
  • Swift Protobuf Compatibility: Convert between static and dynamic messages
  • Type Registry: Centralized type management and lookup

Examples

The library includes 38 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 ApiGateway
swift run MessageTransform
swift run ValidationFramework

Examples are organized by topic:

  • Basic Usage (4 examples): Getting started
  • Dynamic Messages (6 examples): Message manipulation
  • Serialization (5 examples): Binary and JSON formats
  • Registry (4 examples): Type management
  • Well-Known Types (8 examples): Google standard types
  • Advanced (6 examples): Complex patterns
  • Real-World (5 examples): Production scenarios

Requirements

  • Swift 5.9+
  • macOS 12.0+ / iOS 15.0+
  • Recommended: SwiftProtoReflect 4.0.0+

Dependencies

Documentation

Use Cases

  • Generic protobuf tools (viewers, debuggers, converters)
  • API gateways with dynamic message routing
  • Data processing pipelines with runtime schema handling
  • Testing tools that generate data for arbitrary schemas
  • Configuration systems using protobuf schemas

Integration with Swift Protobuf

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()

Testing

The library has comprehensive test coverage covering all functionality and edge cases.

License

MIT License. See LICENSE for details.

About

SwiftProtoReflect is a dynamic Protocol Buffers library for Swift, enabling reflection-based message handling, serialization, and deserialization without the need for precompiled .proto files.

Topics

Resources

License

Stars

Watchers

Forks