How to Build a Math Practice App in SwiftUI
A Math Practice app presents randomised arithmetic drills, tracks scores, and rewards correct answers with satisfying animations — perfect for students, parents, and educators who want a focused, distraction-free learning tool.
Prerequisites
- Xcode 16 or later installed on macOS Sequoia or later
- Basic familiarity with Swift — variables, structs, and functions
- An Apple Developer account (free tier is fine for Simulator testing)
Step-by-Step Guide
1. Define the Data Model
Use a SwiftData @Model class to persist each drill session so players can review their history across launches.
import SwiftData
import Foundation
@Model
final class DrillSession {
var date: Date
var totalQuestions: Int
var correctAnswers: Int
var operationType: String // "+", "-", "×", "÷"
init(operationType: String) {
self.date = .now
self.totalQuestions = 0
self.correctAnswers = 0
self.operationType = operationType
}
}
2. Build the Core UI View
Create a full-screen drill view that shows the current problem, accepts a numeric answer, and displays a live score counter.
struct DrillView: View {
@State private var problem = ""
@State private var answer = ""
@State private var score = 0
@State private var shake = false
var body: some View {
VStack(spacing: 32) {
Text("Score: \(score)")
.font(.headline).foregroundStyle(.secondary)
Text(problem)
.font(.system(size: 52, weight: .bold))
.offset(x: shake ? -8 : 0)
TextField("Answer", text: $answer)
.keyboardType(.numberPad)
.font(.largeTitle).multilineTextAlignment(.center)
Button("Check", action: checkAnswer)
.buttonStyle(.borderedProminent).controlSize(.large)
}
.padding()
.onAppear(perform: nextProblem)
}
}
3. Implement Arithmetic Drills
Generate random problems, validate the answer, animate feedback, and advance to the next question — all in a handful of Swift functions.
extension DrillView {
func nextProblem() {
let a = Int.random(in: 1...12)
let b = Int.random(in: 1...12)
problem = "\(a) × \(b) ="
answer = ""
}
func checkAnswer() {
guard let input = Int(answer) else { return }
let parts = problem.split(separator: " ").compactMap { Int($0) }
if input == parts[0] * parts[1] {
score += 1
withAnimation(.spring(response: 0.3)) { nextProblem() }
} else {
withAnimation(.default) { shake = true }
DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
shake = false
}
}
}
}
Common Pitfalls
- Division by zero: Always clamp the divisor to at least 1 when generating division problems to avoid a crash or nonsensical question.
- Animation state leaks: Reset
shakeand other transient state inonAppearso returning from a background session doesn't leave the UI in a broken state. - SwiftData context on the main actor: Mutate
@Modelobjects only on the@MainActorthread; doing so in a background task withoutawaitcauses silent data corruption in iOS 17.
Monetization: Ad-Supported
An ad-supported model lets you ship for free and grow an audience quickly — integrate the Google Mobile Ads SDK (or Apple's SKAdNetwork-compatible alternative) and show a banner between drill rounds rather than mid-question to avoid disrupting the learning flow. Pair this with a StoreKit 2 "Remove Ads" one-time purchase (Product.purchase(_:)) so power users can pay once and practice without interruptions; even a $0.99 price point converts well when parents appreciate the clean experience.
Ship Faster with Soarias
Soarias scaffolds your entire Math Practice project — SwiftData models, drill logic, StoreKit paywall, and App Store metadata — in minutes rather than days. As a local-first desktop app built for Claude Code users, it runs entirely on your Mac ($79, one-time), so your code and API keys never leave your machine. Skip the boilerplate and spend your two days on gameplay polish instead of project setup.
Related Tutorials
FAQ
Do I need an Apple Developer account?
You need a free Apple ID to run the app on Simulator and on your own device via Xcode direct install. To distribute on the App Store or TestFlight you'll need 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 Xcode Organizer to upload the build to App Store Connect. Fill in your app's metadata, screenshots, and privacy labels, set your pricing, and click Submit for Review. Apple typically reviews beginner-complexity apps within 24–48 hours.
Last reviewed: 2026-05-12 by the Soarias team.