```html How to Build a Instrument Tuner App in SwiftUI (2026)

How to Build an Instrument Tuner App in SwiftUI

An Instrument Tuner app listens through the microphone, identifies the nearest musical pitch in real time, and shows musicians how many cents sharp or flat they are. It's the perfect intermediate SwiftUI project for developers who want hands-on experience with AVFoundation audio pipelines and Accelerate FFT on iOS.

iOS 17+ · Xcode 16+ · SwiftUI Complexity: Intermediate Updated: 2026-05-12

Prerequisites

Step-by-Step Guide

1. Define the Data Model

Use a SwiftData @Model class to persist each tuning session so users can review historical accuracy over time.

import SwiftData
import Foundation

@Model
final class TunerSession {
    var instrument: String
    var detectedNote: String
    var centOffset: Double
    var timestamp: Date = Date()

    init(instrument: String, note: String, cents: Double) {
        self.instrument = instrument
        self.detectedNote = note
        self.centOffset = cents
    }
}

2. Build the Core Tuner UI

Create a TunerView that displays the detected note name, a needle gauge, and a colour-coded cent readout that turns green when the player is within ±5 cents.

struct TunerView: View {
    @StateObject private var tuner = TunerEngine()
    var body: some View {
        VStack(spacing: 24) {
            Text(tuner.currentNote)
                .font(.system(size: 72, weight: .bold, design: .rounded))
            TunerNeedle(cents: tuner.centOffset)
                .frame(height: 160)
            Text(String(format: "%+.1f ¢", tuner.centOffset))
                .foregroundStyle(abs(tuner.centOffset) < 5 ? .green : .red)
        }
        .onAppear { tuner.start() }.onDisappear { tuner.stop() }
    }
}

3. Implement Pitch Detection with AVFoundation & Accelerate

Wire up the device microphone with AVAudioEngine, tap a 4096-sample buffer, and run an Accelerate FFT to locate the dominant frequency bin on a background thread.

final class TunerEngine: ObservableObject {
    @Published var currentNote = "–"
    @Published var centOffset: Double = 0
    private let engine = AVAudioEngine()
    func start() {
        let node = engine.inputNode
        node.installTap(onBus: 0, bufferSize: 4096,
            format: node.outputFormat(forBus: 0)) { [weak self] buf, _ in
            self?.detectPitch(buffer: buf)
        }
        try? engine.start()
    }
    func stop() { engine.stop() }
}

Common Pitfalls

Monetization: One-Time Purchase

A one-time purchase is the cleanest fit for a tuner — musicians hate recurring fees for a utility they've owned for years. Implement it with StoreKit 2's Product.purchase() API: gate advanced features (chromatic history, custom temperaments, or an ad-free experience) behind a single non-consumable in-app purchase. StoreKit 2 handles receipt verification server-side, so you need zero backend infrastructure; just check Transaction.currentEntitlements on app launch to restore purchases automatically across the user's devices.

Ship Faster with Soarias

Soarias scaffolds your entire Instrument Tuner project — AVAudioEngine tap setup, Accelerate FFT boilerplate, SwiftData schema, StoreKit 2 purchase flow, and Fastlane lanes for screenshots and App Store submission — in minutes instead of days. The one-time $79 desktop app runs locally alongside Claude Code, so your source code never leaves your machine while Soarias handles the tedious wiring that would otherwise eat your weekend.

Related Tutorials

FAQ

Do I need an Apple Developer account?

You can build and run the tuner on the iOS Simulator with a free Apple ID. However, testing real microphone input requires a physical device, and distributing on the App Store requires a paid Apple Developer Program membership ($99/year).

How do I submit to the App Store?

Archive your app in Xcode (Product › Archive), then use the Organizer to validate and upload to App Store Connect. Fill in your app's metadata, screenshots, and privacy labels, set your one-time purchase price, and submit for review — Apple's typical review time is 24–48 hours for new apps.

Last reviewed: 2026-05-12 by the Soarias team.

```