# Licensing

SWIFTFramework is a licensed component. Validation runs inside every `SwiftMessage` constructor, including messages created by `SwiftParser.GetMessage`.

## Runtime key

Set the key once at process start, before any message object is created. **Never hard-code a purchased key in samples or public source.**

```csharp
string key = Environment.GetEnvironmentVariable("SWIFTFRAMEWORK_RUNTIME_LICENSE_KEY");
if (!string.IsNullOrWhiteSpace(key))
    Licensing.RunTimeLicenseKey = key.Trim();
```

Or omit the assignment and store the key in .NET User Secrets (see below).

Run a sample after exporting the key:

```bash
export SWIFTFRAMEWORK_RUNTIME_LICENSE_KEY='your-purchased-key'
dotnet run --project Framework/SourceCode/ConsoleSample/ConsoleSample.csproj
```

From this release package:

```bash
export SWIFTFRAMEWORK_RUNTIME_LICENSE_KEY='your-purchased-key'
dotnet run --project samples/ParseAndModify/ParseAndModify.csproj
```

The value is the **hex key only** (groups of four hex digits separated by `-`). Do not include the generator prefix (`SWF-26-2x-SL-…`).

## Product moniker (2026.2)

Keys embed a product code `SWF-YY-RX`:

| Part | Meaning | 2026.2 value |
|---|---|---|
| `YY` | Year | `26` |
| `R` | Release in that year | `2` |
| `X` | License type | `0`–`4` |

This build accepts:

```
SWF-26-20
SWF-26-21
SWF-26-22
SWF-26-23
SWF-26-24
```

Keys generated for 2026.1 (`SWF-26-10` … `SWF-26-14`) are **rejected**.

Design-time keys (Visual Studio / designer) and runtime keys both validate. Applications should ship a **runtime** key.

## User Secrets

If `RunTimeLicenseKey` is not set in code, the library looks for .NET User Secrets on first access.

User secrets id: `SWIFTFramework`

Locations:

- Windows: `%APPDATA%\Microsoft\UserSecrets\SWIFTFramework\secrets.json`
- macOS / Linux: `~/.microsoft/usersecrets/SWIFTFramework/secrets.json`

Accepted JSON shapes:

```json
{ "SWIFTFramework:RuntimeLicenseKey": "HHHH-HHHH-..." }
```

```json
{ "SWIFTFramework": { "RuntimeLicenseKey": "HHHH-HHHH-..." } }
```

```json
{ "RuntimeLicenseKey": "HHHH-HHHH-..." }
```

## Failure behavior

Missing, empty, malformed, or wrong-product keys cause:

```csharp
System.ComponentModel.LicenseException
```

Typical message:

> A valid license cannot be granted for the type SWIFTFramework.SwiftMessage.

Catch this at startup if you want a clearer application error.

## Changing the key at runtime

`RuntimeEngine` caches validation per key value. Assigning a new `Licensing.RunTimeLicenseKey` is enough for the next `SwiftMessage` construction — a different key re-validates automatically.

## What is not used in this release

- `licenses.licx` / `LC.exe` design-time embedding
- WinForms license install dialogs (those exist only on the legacy .NET Framework line)
- Evaluation / trial UI

## Checklist for shipping an app

1. Obtain a **2026.2 runtime** key for your serial.
2. Set it in code or User Secrets before the first parse/create.
3. Do not commit customer keys to public source if that is a concern — User Secrets or configuration is preferred.
