Obfuscated 2.0.0
Obfuscated 2.0.0
Obfuscated 2.0.0 adds user-defined obfuscation steps, extracts shared macro infrastructure into ObfuscatedMacroSupport, and publishes ObfuscatedCore as a standalone product. Built-in #Obfuscated usage is unchanged for typical apps; this is a major release because public enums and CryptoMaterial gained new cases and fields.
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.0.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
Custom obfuscation steps
Define your own transforms with the ObfuscationStep protocol and use them in #Obfuscated via .custom(id:parameters:):
let secret = #Obfuscated(
"Custom protected secret",
methods: [.custom(id: "rot13", parameters: ObfuscationParameters(bytes: [13]))]
)Custom steps require a user-owned macro plugin target that links ObfuscatedMacroSupport and registers step types before expansion. Macro expansion runs in a plugin process that cannot import your app module.
Full setup guide: docs/CUSTOM_OBFUSCATION_STEPS.md
Working example in this repo: Demo/ObfuscatedDemoSupport (ObfuscatedDemoKit + ObfuscatedDemoMacros + DemoRot13Step).
ObfuscatedMacroSupport extraction
Macro parsing, expansion building, and ObfuscatedMacro now live in the ObfuscatedMacroSupport library. ObfuscatedMacros is a thin default compiler plugin (built-in methods only). Advanced users link ObfuscatedMacroSupport when building custom plugins.
New public types
| Type | Role |
|---|---|
ObfuscationStep |
Protocol for user-defined encode/decode transforms |
ObfuscationParameters |
Literal byte parameters embedded in macro expansions |
ObfuscationStepRegistry |
Registers custom steps for pipeline + macro encode |
CustomMaterialEntry |
Per-step persisted state in CryptoMaterial |
ObfuscationMacroConfiguration |
Plugin init hook to run step registration |
Re-exported from Obfuscated alongside existing ObfuscationMethod, ObfuscatedKey, etc.
Demo package
The demo app's custom-step wiring moved out of the root package into a local SPM package at Demo/ObfuscatedDemoSupport/. The Xcode demo imports ObfuscatedDemoKit from that package instead of depending on the root Obfuscated product directly.
Breaking changes (from 1.0.0)
ObfuscationMethod — new case
case custom(id: String, parameters: ObfuscationParameters)Impact: Exhaustive switch statements over ObfuscationMethod must handle .custom or add @unknown default.
No impact for typical usage: #Obfuscated("...", methods: [.xor(key: 0x5A), .base64]) with built-in method literals.
ObfuscationError — new cases
unknownCustomStep(String)missingCustomMaterial
Impact: Exhaustive switch statements over ObfuscationError must handle the new cases.
No impact for typical #Obfuscated callers — ObfuscatedRuntime._decode catches errors internally.
CryptoMaterial — new field
public var customEntries: [CustomMaterialEntry]
public init(entries: [CryptoEntry] = [], customEntries: [CustomMaterialEntry] = [])Impact: Code that pattern-matches CryptoMaterial exhaustively or assumes a fixed shape may need updates.
No impact for CryptoMaterial(entries: [...]) call sites — customEntries defaults to [].
Macro module layout
Macro implementation code moved from ObfuscatedMacros to ObfuscatedMacroSupport. The default #Obfuscated declaration still points at ObfuscatedMacros.ObfuscatedMacro.
Impact: Projects that imported or @testable imported ObfuscatedMacros internals directly must migrate to ObfuscatedMacroSupport.
No impact for import Obfuscated consumers.
Migration from 1.0.0
-
Typical app (built-in methods only) — bump the dependency and rebuild:
.package(url: "https://github.com/tomisacat/Obfuscated.git", from: "2.0.0")
No source changes expected.
-
Exhaustive enum switches — add cases for
.custom,unknownCustomStep, andmissingCustomMaterial, or use@unknown default. -
Custom steps (new in 2.0) — follow CUSTOM_OBFUSCATION_STEPS.md:
- Implement
ObfuscationStep - Add a
.macrotarget withObfuscatedMacroSupport - Register steps in the plugin
initand at app launch for runtime decode - Point
#Obfuscatedat your plugin with#externalMacro
- Implement
-
Pin to 1.0.0 if you are not ready to upgrade:
.package(url: "https://github.com/tomisacat/Obfuscated.git", exact: "1.0.0")
Unchanged from 1.0.0
#Obfuscatedmacro signature and default plugin module (ObfuscatedMacros)- All built-in obfuscation methods (XOR, bit shift, bit OR, Base64, AES-GCM, ChaCha, HMAC, HKDF, ECIES)
- Static string interpolation (
\("...")literals folded at compile time) ObfuscatedRuntime._decode(bytes:methods:material:)entry point- Platform and Swift version requirements
Documentation
- README — quick start, products, 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
48 unit tests cover encode/decode round-trips, 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.0.0