Appendix V: Take A Chance On Me (Shop Manual)

Status: Live on the App Store (US + Canada only). v2.0. App Apple ID 6753626820. Bundle ID com.inkwell.TakeAChanceOnMe. iPhone + iPad universal. GPL v3. Public repo at github.com/fluhartyml/TakeAChanceOnMeV1.0.2 (the V1.0.2 in the repo name is historical; the project is on v2.0). Take A Chance On Me is the smallest-scale shipping reference app in the book's roster. Three Swift files do the entire job: a random-number generator with a gradient background, a dice-bag picker, and an about / feedback footer. Book 06 (Controls) Live Reference reaches for this app's DiceBagView and FeedbackView when it needs the most minimal possible production examples of Toggle, Button, and segmented Picker.

What it is

An iPhone / iPad app that picks a random number between 1 and a maximum the user types in. The number-entry surface is a number-pad text field with a "Done" toolbar button to dismiss; the result renders as a large, comma-formatted number on a gradient purple-to-blue background. v2.0 added a Dice Bag view where the user toggles which standard dice (d4, d6, d8, d10, d12, d20, d100) are included, taps Generate, and gets a per-die roll plus a sum. That's the whole app.

Architecture overview

Three primary Swift files plus the About and Feedback surfaces. No SwiftData, no network, no entitlements.

Why Book 06 points here

Book 06 (Controls) explicitly reaches for this app as the smallest-scale shipping source for Button, Toggle, and Picker. The chapter's claim: you don't need a complex app to demonstrate the control primitives. DiceBagView uses Toggle per die (binary state, drives a published @Observable property) and Buttons for the actions (Generate, Clear Results, keyboard Done). FeedbackView uses a segmented Picker with three cases. That's the entire chapter's surface mapped to one app you can build and read end-to-end in under an hour.

Smallness is the teaching. Larger apps in the roster (CryoTunes, LockBox) demonstrate the same primitives at scale; this one demonstrates them at the floor.

The number-pad keyboard pattern

Worth singling out for the chapter on input: TextField bound to a numeric state, .keyboardType(.numberPad) to lock to digits, .toolbar { ToolbarItemGroup(placement: .keyboard) { Spacer(); Button("Done") { ... } } } for the Done button that gives the user a way out (the number pad has no Return key), plus an onTapGesture on the surrounding view to dismiss the keyboard when the user taps the background. Four small modifiers and a toolbar item, all standard SwiftUI — no first-responder management, no UIResponder tricks.

Build + deployment

Known gotchas

Sources