Skip to main content

Building PayoffPilot: A Privacy-First iOS App

When I started looking for a debt payoff calculator app, I found plenty of options—but they all wanted my financial data. Bank account connections, cloud sync, accounts that track everything. For something as personal as debt, that felt wrong.

So I built PayoffPilot, a privacy-first debt payoff calculator that keeps all your data on your device.

The Problem

The typical debt payoff app workflow:

  1. Create an account
  2. Connect your bank accounts (via Plaid or similar)
  3. Hope they don’t get hacked
  4. Watch ads or pay a subscription

I wanted something different:

  • No account required
  • No cloud sync
  • No data collection
  • One-time purchase (if any monetization)

Design Decisions

Privacy by Architecture

The first decision was fundamental: no backend. Everything stays on the device.

// All data stored locally using SwiftData
@Model
class Debt {
    var name: String
    var balance: Decimal
    var interestRate: Decimal
    var minimumPayment: Decimal
    var dateAdded: Date

    // Computed locally, never transmitted
    var payoffDate: Date? {
        PayoffCalculator.calculatePayoffDate(for: self)
    }
}

No API calls, no analytics SDK, no third-party tracking. The app literally cannot share your data because it has no way to.

Debt Payoff Strategies

I implemented the two most popular strategies:

Debt Avalanche: Pay off highest interest rate first. Mathematically optimal—saves the most money.

Debt Snowball: Pay off smallest balance first. Psychologically effective—builds momentum with quick wins.

enum PayoffStrategy {
    case avalanche  // Highest interest first
    case snowball   // Smallest balance first

    func sortDebts(_ debts: [Debt]) -> [Debt] {
        switch self {
        case .avalanche:
            return debts.sorted { $0.interestRate > $1.interestRate }
        case .snowball:
            return debts.sorted { $0.balance < $1.balance }
        }
    }
}

The Calculation Engine

The payoff calculator handles:

  • Compound interest calculations
  • Extra payment allocation
  • Multiple debt scenarios
  • Payoff timeline projections
struct PayoffCalculator {
    static func calculatePayoff(
        debts: [Debt],
        strategy: PayoffStrategy,
        extraPayment: Decimal
    ) -> PayoffPlan {
        var plan = PayoffPlan()
        var remainingDebts = strategy.sortDebts(debts)
        var month = 0

        while !remainingDebts.isEmpty {
            month += 1
            // Apply minimum payments
            // Allocate extra payment to target debt
            // Track interest paid
            // Remove paid-off debts
        }

        return plan
    }
}

Technical Challenges

Challenge 1: Accurate Interest Calculations

Financial calculations need precision. Using Double leads to rounding errors that accumulate over months of projections.

Solution: Use Decimal for all monetary values and NSDecimalNumber for complex calculations.

extension Decimal {
    func monthlyInterest() -> Decimal {
        self / 12 / 100
    }

    func applyInterest(to balance: Decimal) -> Decimal {
        balance * (1 + self.monthlyInterest())
    }
}

Challenge 2: SwiftUI Performance

Recalculating payoff projections on every input change caused lag. A user adjusting their extra payment slider shouldn’t wait for calculations.

Solution: Debounce calculations and use @MainActor for UI updates.

@Observable
class PayoffViewModel {
    var extraPayment: Decimal = 0 {
        didSet {
            debounceCalculation()
        }
    }

    private var calculationTask: Task<Void, Never>?

    private func debounceCalculation() {
        calculationTask?.cancel()
        calculationTask = Task {
            try? await Task.sleep(for: .milliseconds(300))
            guard !Task.isCancelled else { return }
            await recalculate()
        }
    }
}

Challenge 3: Data Persistence

I needed local persistence that:

  • Survives app updates
  • Handles schema migrations
  • Doesn’t require a backend

Solution: SwiftData with versioned schemas.

@Model
class Debt {
    // v1 properties...

    // v2: Added notes field
    var notes: String = ""
}

// Migration handled automatically by SwiftData

What I Learned

1. Privacy is a Feature

Users appreciate knowing their financial data isn’t being harvested. The App Store reviews consistently mention privacy as a reason for choosing PayoffPilot.

2. Simple Beats Feature-Rich

Early versions had budget tracking, payment reminders, bank import. Users were overwhelmed. I stripped it back to the core: enter debts, see payoff plan.

3. SwiftUI is Ready for Production

After years of UIKit, SwiftUI felt limiting at first. But for new projects, the development speed is unmatched. Previews alone save hours.

4. Side Projects Need Scope Limits

As a working engineer with a family, I had limited time. Setting a strict MVP scope—debt entry, two strategies, payoff visualization—kept the project shippable.

Results

  • Downloads: Steady organic growth through App Store search
  • Ratings: 4.8 stars average
  • Reviews: Consistently mention privacy and simplicity
  • Support requests: Minimal (simple app = fewer issues)

Future Plans

Based on user feedback, I’m considering:

  • Apple Watch complication showing payoff progress
  • Widgets for debt-free countdown
  • iCloud sync (optional, encrypted, still no account)
  • One-time unlock for premium features

Key Takeaways

Building PayoffPilot reinforced several principles:

  1. Start with the problem, not the technology. The privacy-first approach defined every technical decision.

  2. Ship something small and complete. A focused app that does one thing well beats a bloated app that does everything poorly.

  3. Your day job skills transfer. The architecture patterns I use at Dell—clean separation, testable code, performance consideration—applied directly.

  4. Side projects keep skills sharp. iOS development is different from DevOps. Having a project forces me to stay current.


PayoffPilot is available on the App Store under Big Beard Apps. Have questions about iOS development or privacy-first design? Connect with me on LinkedIn.

👨‍💻

Raul C. Peña

Senior Software Engineer at Dell Technologies. Air Force veteran, former real estate broker, self-taught coder. Passionate about DevOps, Hashicorp Vault, and building things that matter.