Obfuscated 2.1.0
Obfuscated 2.1.0 extends #Obfuscated beyond strings to Int, Bool, Data, and enums. This is an additive minor release — existing string macro usage, built-in methods, and custom step wiring are unchanged.
Requirements
- macOS 15+, iOS 14+, tvOS 14+, watchOS 7+, macCatalyst 14+
- Swift 6.2+
- Xcode 16+ (macro plugin support)
Installation
Add Obfuscated via Swift Package Manager:
dependencies: [
.package(url: "https://github.com/tomisacat/Obfuscated.git", from: "2.1.0"),
],
targets: [
.target(
name: "<YourAppTarget>",
dependencies: ["Obfuscated"]
),
]For an Xcode app target, use File → Add Package Dependencies and enter https://github.com/tomisacat/Obfuscated.git.
Products
| Product | Use when |
|---|---|
Obfuscated |
Default — built-in methods only; #Obfuscated via ObfuscatedMacros |
ObfuscatedCore |
Direct pipeline access, tests, or custom step libraries |
ObfuscatedMacroSupport |
Building a user-owned macro plugin with custom ObfuscationStep types |
Highlights
Typed value obfuscation
#Obfuscated now accepts compile-time literals for multiple types and returns ordinary values at runtime — no wrapper types, no manual decode:
| Type | Example |
|---|---|
String |
#Obfuscated("secret", methods: [...]) |
Int |
#Obfuscated(443, methods: [...]) |
Bool |
#Obfuscated(true, methods: [...]) |
Data |
#Obfuscated([0xDE, 0xAD], methods: [...]) |
| Enum case | #Obfuscated(Environment.production, methods: [...]) — requires CaseIterable |
RawRepresentable |
#Obfuscated(1, as: Color.self, methods: [...]) |
let port: Int = #Obfuscated(443, methods: [.xor(key: 0x11)])
let enabled: Bool = #Obfuscated(true, methods: [.xor(key: 1)])
let token: Data = #Obfuscated([0xDE, 0xAD, 0xBE, 0xEF], methods: [.xor(key: 0x5A)])
enum Environment: CaseIterable { case production, staging }
let env: Environment = #Obfuscated(Environment.production, methods: [.xor(key: 0x3C)])
enum Role: String { case admin, guest }
let role: Role = #Obfuscated("admin", as: Role.self, methods: [.xor(key: 0x2A)])Enum semantics:
Type.caseobfuscates the case name as UTF-8. RequiresCaseIterableandSendable. Applies to anyCaseIterableenum — even when it also has anIntorStringraw value.as: Type.selfobfuscates the raw value (Int→ 8-byte big-endianInt64;String→ UTF-8). RequiresRawRepresentable. Use when you want the stored raw value hidden.- Both forms are valid when an enum conforms to
CaseIterableandRawRepresentable:#Obfuscated(Color.red, ...)hides"red";#Obfuscated(1, as: Color.self, ...)hides1. - Enums without a raw value (e.g.
Environment) only support theType.caseform.
See README — Limitations for the full caveat list.
All types share the same obfuscation method pipeline (XOR, crypto, custom steps, etc.) after per-type serialization to plaintext bytes.
New public types
| Type | Role |
|---|---|
ObfuscatedValue |
Protocol for serializing values to/from plaintext bytes before/after the pipeline |
ObfuscatedEnumSupport |
CaseIterable case lookup by decoded case name |
ObfuscatedRawRepresentableSupport |
Encode/decode helpers for RawRepresentable raw values |
Built-in ObfuscatedValue conformances: String, Int, Bool, Data.
Re-exported from Obfuscated as public typealias ObfuscatedValue.
Pipeline and runtime extensions
| API | Role |
|---|---|
ObfuscationPipeline.encode(bytes:methods:) |
Byte-level encode entry point |
ObfuscationPipeline.encode<T: ObfuscatedValue>(_:methods:) |
Generic value encode |
ObfuscationPipeline.decodeBytes(_:methods:) |
Reverse pipeline to plaintext bytes |
ObfuscationPipeline.decode<T: ObfuscatedValue>(_:methods:as:) |
Generic value decode |
ObfuscatedRuntime._decode(bytes:methods:material:as:) |
Typed runtime decode for macro expansions |
ObfuscatedRuntime._decodeRawRepresentable(...) |
Raw-representable enum decode |
ObfuscatedRuntime._decodeCaseIterable(...) |
Case-name enum decode |
Existing ObfuscationPipeline.encode(_:methods:) / decode(_:methods:) -> String and ObfuscatedRuntime._decode(bytes:methods:material:) -> String are unchanged.
Demo updates
The demo app adds a Typed Values section covering Int, Bool, Data, CaseIterable enum cases, and RawRepresentable enums. ObfuscatedDemoKit mirrors the new macro overloads.
Migration from 2.0.0
-
Typical app (strings only) — bump the dependency and rebuild:
.package(url: "https://github.com/tomisacat/Obfuscated.git", from: "2.1.0")
No source changes expected.
-
Adopting typed values — use the new overloads where compile-time literals fit your use case. Variables and runtime expressions are still not supported.
-
Custom macro plugin authors — rebuild your plugin. If you exhaustively switch on
ObfuscatedMacroError, add cases formissingValueLiteralandinvalidTypeExpression. -
Pin to 2.0.0 if you are not ready to upgrade:
.package(url: "https://github.com/tomisacat/Obfuscated.git", exact: "2.0.0")
Unchanged from 2.0.0
- String
#Obfuscatedoverload, expansion shape, and default plugin (ObfuscatedMacros) - All built-in and custom obfuscation methods
ObfuscationMethod,ObfuscationError, andCryptoMaterialshapes- Static string interpolation (
\("...")literals folded at compile time) - Custom step setup via
ObfuscationStepand user-owned macro plugins - Platform and Swift version requirements
Limitations
See also the canonical list in README — Limitations.
- Compile-time literals only — not variables or runtime expressions
- Enum cases via
Type.caserequireCaseIterableandSendable; associated values are not supported Type.caseworks for anyCaseIterableenum, includingInt- orString-backed enums that also conform toRawRepresentable— it obfuscates the case name, not the raw value- When an enum is both
CaseIterableandRawRepresentable, choose the overload by what you want hidden:#Obfuscated(Color.red, ...)→ name"red";#Obfuscated(1, as: Color.self, ...)→ raw value1 - Enums without
RawRepresentable(e.g.Environment.production) only support theType.caseform
Documentation
- README — quick start, typed values, and method reference
- ARCHITECTURE.md — Mermaid diagrams and data flow
- DOCUMENTATION.md — full source reference
- CUSTOM_OBFUSCATION_STEPS.md — custom step and macro plugin setup
- Demo app — SwiftUI catalog on iOS and macOS
Testing
60 unit tests cover encode/decode round-trips, typed values (ObfuscatedValueTests), built-in and custom step pipelines, macro parsing, and expansion. CI runs swift test and demo app builds on every push and pull request to main.
License
MIT License — see LICENSE.
Tag: 2.1.0