Appendix Q: NightGardDDNS (Shop Manual)

Status: v1.0.0 production ready. Self-distributed — not available on the App Store (the App Store doesn't allow this kind of app; see "Why not the App Store" below). GPL v3. Public repo at github.com/fluhartyml/NightGard under Modules/NightGardDDNS. Distributed as a Swift Package (reusable library) plus a demo app. NightGardDDNS provides automatic Dynamic DNS (DDNS) update functionality for macOS and iOS. It monitors the user's public IP address and updates a DDNS provider (currently DuckDNS) when the IP changes.

What it does

A user with a dynamic IP address from their ISP — meaning the public IP can change without warning — needs a way to keep a domain name pointing at their current address. Dynamic DNS providers (DuckDNS, No-IP, DynDNS) give the user a domain name; the user's job is to tell the provider whenever the IP changes. NightGardDDNS automates that telling-step.

The flow:

  1. App launches; the user configures their DuckDNS domain and token in Settings.
  2. The app reads the local network IP via BSD sockets (getifaddrs on en0 / en1).
  3. The app fetches the public IP via fallback services (ipify.org, icanhazip.com, ifconfig.me).
  4. If the public IP has changed since last check, the app POSTs an update to DuckDNS with the user's domain + token + new IP.
  5. The app repeats steps 2–4 on a configurable timer (default: every 5 minutes).

Architecture overview

Small project. Swift Package + demo app pattern.

Settings persistence

Configuration (domain, token, update interval) persists in UserDefaults. No external dependencies, no SwiftData, no networking beyond the public-IP probe and the DuckDNS update. The token is sensitive (it's the key to updating the user's DDNS record) but the app stores it in UserDefaults for simplicity. A production hardening pass would migrate the token to the system keychain.

Why not the App Store

App Store policy effectively disallows this kind of app. Three concrete reasons:

None of these are absolute App Store rejections every time, but together they make App Store distribution costly to attempt and likely to be rejected on review. Self-distribution sidesteps all three.

How to get it (self-distribution path)

NightGardDDNS is distributed through three paths:

  1. GitHub clone-and-build. The repo is public; readers clone, open in Xcode, and build for their own device. This is the default path for the book's roster and the canonical way to get NightGardDDNS.
  2. Swift Package import. Other Mac / iOS projects can add NightGardDDNS as a Swift Package dependency and use the library code directly — the demo app is the example, not the only deliverable. The package follows the "Lego brick" reuse pattern of the NightGard Module Library.
  3. Mac Developer ID signed direct download (future). Mac distribution outside the App Store uses Apple's Developer ID signing + notarization process. The app gets signed and notarized, the user downloads it from a website, and macOS Gatekeeper accepts it because it's signed and notarized. iOS direct distribution is more constrained — AltStore, TestFlight, or enterprise certificates are the options — and NightGardDDNS doesn't currently target any of them for end-user iOS distribution.

The Module Library context

NightGardDDNS was extracted from a larger project (wWw NGPortal) in November 2025 as part of the NightGard Module Library initiative — a project to break common app functionality into reusable Swift packages developers can use to rapidly build applications without reinventing the same code. NightGardDDNS is one Lego brick; PlaylistLocker (Appendix P) is another. The pattern is: build the feature once for a real app, harden it, extract the reusable part into a package, ship both the demo app (to prove it works) and the package (so others can use it).

Build + deployment

Smart update logic

The service is intentionally conservative about hitting DuckDNS:

Known gotchas

Sources