Skip to content

P4 #5: Replace force-unwrapped URLs in AuthenticationManager with URL.api(path:) helper #123

Description

@dprodger

Context

From doc/architecture-review-2026-04.mdP4 #5.

apps/Shared/Auth/AuthenticationManager.swift has eight force-unwrapped URL constructions. The review lists the specific lines:

  • Line 104
  • Line 160
  • Line 216
  • Line 288
  • Line 330
  • Line 355
  • Line 497
  • Line 630

Each is the pattern:

let url = URL(string: "\(NetworkManager.baseURL)/auth/login")!

These work because the strings are all constants and known to parse. But:

  1. A typo in any one of them crashes the app with Fatal error: Unexpectedly found nil.
  2. The pattern makes it harder to grep for API paths — they are scattered across the file as interpolated strings.
  3. If NetworkManager.baseURL ever becomes dynamic (different env / staging), the compiler will not help catch misuses.

Proposed fix

Add a small helper on URL:

extension URL {
    static func api(path: String) -> URL {
        guard let url = URL(string: "\(NetworkManager.baseURL)\(path)") else {
            preconditionFailure("Invalid API URL: \(NetworkManager.baseURL)\(path)")
        }
        return url
    }
}

Then replace every force-unwrap:

// Before
let url = URL(string: "\(NetworkManager.baseURL)/auth/login")!

// After
let url = URL.api(path: "/auth/login")

The preconditionFailure still crashes on an invalid URL (the behavior is identical to force-unwrap) but it gives a descriptive error instead of Fatal error: Unexpectedly found nil, and centralizes the construction so a future dynamic base URL has one place to change.

Other files to check

The review only called out AuthenticationManager.swift, but the same pattern likely exists in:

  • NetworkManager.swift
  • FavoritesManager.swift
  • RepertoireManager.swift
  • RecordingDetailViewModel.swift — has one at URL(string: "\(NetworkManager.baseURL)/recordings/\(recordingId)")

Grep for URL(string:.*baseURL and fix them all in one pass.

Not in scope

  • Changing how NetworkManager.baseURL is defined or configured.
  • Rewriting the request methods themselves.

Context links

  • apps/Shared/Auth/AuthenticationManager.swift — the eight lines listed above
  • apps/Shared/Support/NetworkManager.swift — probably has more of the same pattern
  • Review doc: doc/architecture-review-2026-04.md (P4 Provide a filer for releases #5)

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions