Contents

haven-apps/havenacknowledgments

A SwiftUI library that automatically generates and displays third-party license acknowledgments for Swift packages.

Features

  • Automatic scanning — reads Package.resolved and LICENSE files from package checkouts at build time
  • 25+ license types — detects MIT, Apache 2.0, BSD, GPL, LGPL, MPL, Creative Commons, and more via SPDX identifiers
  • Ready-to-use UI — searchable, platform-adaptive SwiftUI views with Markdown license rendering
  • Platform nativeNavigationSplitView on macOS, NavigationStack on iOS
  • Manual licenses — include vendored or non-SPM dependencies via a Licenses/ directory
  • SPM & Xcode — works with both Swift Package Manager and Xcode project files
  • Swift 6 concurrency — strict Sendable conformance and @Observable data loading
  • Localized — all UI text ships in 50 languages, including right-to-left support for Arabic, Hebrew, and Urdu

Requirements

| | Minimum | |---|---| | iOS | 26+ | | macOS | 26+ | | Swift | 6.3+ | | Xcode | 26+ |

Installation

Swift Package Manager

Add HavenAcknowledgments as a dependency in your Package.swift:

dependencies: [
    .package(url: "https://github.com/Haven-Apps/HavenAcknowledgments.git", from: "1.0.0")
]

Then add the library and the build plugin to your target:

.target(
    name: "MyApp",
    dependencies: ["HavenAcknowledgments"],
    plugins: [
        .plugin(name: "HavenAcknowledgmentsPlugin", package: "HavenAcknowledgments")
    ]
)

Xcode

  1. Go to File > Add Package Dependencies and enter the repository URL.
  2. Add HavenAcknowledgments to your target's Frameworks, Libraries, and Embedded Content.
  3. Add HavenAcknowledgmentsPlugin under Build Phases > Run Build Tool Plug-ins.

Usage

Display as a View

Drop HavenAcknowledgmentsView into any SwiftUI hierarchy:

import HavenAcknowledgments

struct SettingsView: View {
    var body: some View {
        HavenAcknowledgmentsView()
    }
}

Present as a Sheet

Use the .acknowledgmentsSheet(isPresented:) modifier for modal presentation:

import HavenAcknowledgments

struct SettingsView: View {
    @State private var showAcknowledgments = false

    var body: some View {
        Button("Acknowledgments") {
            showAcknowledgments = true
        }
        .acknowledgmentsSheet(isPresented: $showAcknowledgments)
    }
}

Custom Data Sources

Load acknowledgments from a non-standard location by conforming to AcknowledgmentsManifestProvider:

struct RemoteManifestProvider: AcknowledgmentsManifestProvider {
    let url: URL

    func loadManifest() async throws -> AcknowledgmentsManifest {
        let (data, _) = try await URLSession.shared.data(from: url)
        return try AcknowledgmentsManifest.decode(from: data)
    }
}

// Then pass it to any view:
HavenAcknowledgmentsView(provider: RemoteManifestProvider(url: myURL))

How It Works

The build plugin runs at build time and:

  1. Parses your project's Package.resolved to discover all dependencies
  2. Locates SPM package checkouts (via .build/checkouts/ or Xcode's DerivedData)
  3. Reads each package's LICENSE file and detects the license type
  4. Merges any manual entries from a Licenses/ directory in your project root
  5. Outputs an Acknowledgments.json manifest as a build resource

At runtime, HavenAcknowledgmentsView loads this manifest and displays a searchable, navigable list of all acknowledged packages with their full license text.

Manual Licenses

To include licenses for dependencies that aren't managed by SPM (such as vendored code or CocoaPods libraries), create a Licenses/ directory at the root of your project:

MyProject/
├── Licenses/
   ├── SomeVendoredLib.txt
   └── AnotherDependency.txt
├── Package.swift
└── Sources/

The generator detects the license type from each file's contents and merges them into the manifest. Entries are deduplicated by name against auto-detected packages.

Architecture

| Module | Purpose | |---|---| | HavenAcknowledgmentsCore | Shared models — Acknowledgment, License, AcknowledgmentsManifest | | HavenAcknowledgments | SwiftUI views, data loading, and public API | | AcknowledgmentsGeneratorTool | Build-time executable that scans dependencies and produces the JSON manifest | | HavenAcknowledgmentsPlugin | SPM/Xcode build tool plugin that invokes the generator |

Documentation

Full API documentation is available as a DocC catalog bundled with the package. Build documentation in Xcode via Product > Build Documentation.

Localized

All UI text is translated into 50 languages.

Arabic (ar), Bangla (bn), Catalan (ca), Chinese Simplified (zh-Hans), Chinese Traditional (zh-Hant), Croatian (hr), Czech (cs), Danish (da), Dutch (nl), English (en), English (en-AU), English (en-CA), English (en-GB), Finnish (fi), French (fr), French Canada (fr-CA), German (de), Greek (el), Gujarati (gu), Hebrew (he), Hindi (hi), Hungarian (hu), Indonesian (id), Italian (it), Japanese (ja), Kannada (kn), Korean (ko), Malay (ms), Malayalam (ml), Marathi (mr), Norwegian (no), Odia (or), Polish (pl), Portuguese Brazil (pt-BR), Portuguese Portugal (pt-PT), Punjabi (pa), Romanian (ro), Russian (ru), Slovak (sk), Slovenian (sl), Spanish Latin America (es-419), Spanish Spain (es-ES), Swedish (sv), Tamil (ta), Telugu (te), Thai (th), Turkish (tr), Ukrainian (uk), Urdu (ur), Vietnamese (vi)

License

HavenAcknowledgments is available under the BSD 3-Clause License. See LICENSE.md for details.

Package Metadata

Repository: haven-apps/havenacknowledgments

Default branch: main

README: README.md