Going Stellar

Home/Methods

Apps · iOS

How we build an iPhone app

We test demand with our own App Store scanner before writing code, keep the engine in a package that can be verified without Xcode, and treat a clean install on the simulator as our first reviewer. Our worked example, Null Field, is built and ready to submit, but it has not been submitted.

Updated

What this covers, and where Null Field stands

This is how we take an iPhone app from an idea to a build we can submit. The worked example is Null Field, a paranormal entertainment app that turns small changes in the phone's magnetometer into words, and says plainly that the words come from measured sensor variation.

The status, stated plainly: Null Field is not on the App Store. We have a validated Release archive, a verification suite of 92 checks that passes, a bilingual interface, the listing and reviewer notes, the privacy answers, 8 screenshots at 1320×2868, and live privacy and support pages. What is missing is the paid Apple Developer Program membership, which we postponed on purpose. Until then the app runs on our own phone under a free signing profile that expires after 7 days, so a script reinstalls it every week.

The name came out of the process. The working title was an active registered trademark of an existing app, and Apple rejects lookalikes under Guideline 4.1. We chose a name that describes what the engine does, a baseline and deviations from it, and promises nothing we do not measure.

Step one: a demand test that measures flow, not stock

Before any code, we scan the App Store ourselves. Our scanner uses Apple's public endpoints without authentication: the search and lookup APIs for metadata, the per-country review feed for dated review text, and the product page for in-app purchase prices, which the API does not return.

The rule that matters is flow over stock. A lifetime rating count only goes up, so it tells you how big a niche once was. We derive a monthly rate from the dated reviews instead. One niche had a leader with 3,774 ratings, which looked beatable, and produced 10 reviews a month across every app in it. It was dead.

Apple's search is broad-match and sorted by popularity, so a query for a niche tool returns general-purpose apps with over a million ratings; an app only counts if every word of the query appears in its name or description. And complaint volume is not demand: across the 34 niches we profiled, the dominant complaint was price, at 25% to 49% of negative reviews in every one. The loudest reviewers are disproportionately the people who do not pay.

Three things disqualify a niche for us: a free canonical tool, whether preinstalled or funded by a university or a community; a top complaint that cannot be fixed, such as metal detectors, where the magnetometer cannot see gold, silver or copper; and Guideline 4.3, which rejects near-duplicate apps from the same developer. Of the niches we ranked, paranormal had the highest measured flow, 8,539 reviews a month.

Step two: an engine you can verify without Xcode

The machine we started on had no Xcode, only the command-line tools. So the engine lives in a Swift package that depends only on Foundation and CryptoKit, with no UIKit and no CoreMotion. It compiles and runs on a Mac without Xcode, and the iOS app is a thin layer that feeds it sensor data.

The command-line tools ship neither XCTest nor Swift Testing, so the tests are an executable target that prints a comparison table. The output can be read, not just ticked. We checked our randomness estimators against the worked examples in NIST SP 800-90B, which reproduce exactly, and the suite caught 4 real bugs that reading the code had missed, including an estimator that scored a source 0 because it was too good.

Judge speed only in release builds: one assessment took 1,266 ms in debug and 10 ms in release.

Step three: build for the device, then check the artefact

"BUILD SUCCEEDED" does not mean installable. With a hand-written Info.plist, Xcode stops injecting the bundle identifier, the executable name and several other keys. The build is clean and the app will not install. A small script now checks the built bundle for those keys before anything else happens.

The first device build covered 5,203 lines that had never been compiled for iOS and produced 3 errors, all outside the verified engine. Everything the harness covered worked first time, which is the argument for the package split.

When code must exist only in simulator builds, we prove it is excluded with a poison test: a deliberate compile error inside the block must break the simulator build and leave the device build untouched. Searching the binary for strings proves nothing, because the code lives in a framework.

Step four: a clean install on the simulator is the first reviewer

An iPhone 16 Pro Max simulator produces 1320×2868 screenshots natively, the 6.9-inch size App Store Connect asks for, so checking the layout at final resolution does not need the phone.

The simulator found a bug the phone could not show. The app asked for the microphone at launch, on a screen that records nothing. On our phone the permission had been granted months earlier, so the prompt never appeared. On a clean install it did, and it would have failed Guideline 5.1.1, which expects permission to be requested at the point of use. The request now sits on the record button.

The simulator has no magnetometer, so the app would wait for calibration forever. We did not fake data. The app can replay a recording made on our real phone at 100 Hz, so the words in the screenshots come from the real engine fed by a real measurement. Only the transport changes.

A structured readiness audit then confirmed 7 of the 36 issues it raised. The English mode was incomplete, with 3 of 5 tabs still in Romanian, and the app always started in Romanian, so an English-speaking reviewer would have read our disclaimer in a language they do not speak. The recording mode also captured the app's own synthetic voice. Each fix now has a permanent check, and before submission the plan is a release review covering security, the privacy manifest, UX and distribution.

Step five: measure on hardware before you trust a threshold

Every trigger threshold was first set on simulation. So we built a field probe into the app: leave the phone on a table for 10 minutes and it reports the real sample rate, the noise, and how many false triggers there would have been. On our phone the magnetometer ran at 100.7 Hz with noise of 0.148 µT, against an assumed 0.15. The simulation held.

What simulation could not have caught: the raw gyroscope has a bias of 0.0168 rad/s at rest, above the textbook threshold for a phone that is not moving. A motion gate built on raw data would never have opened. The fix is the bias-corrected rotation rate.

The probe also settled a listing question. A 1600 W hair dryer was visible only with the phone touching it; at 2 to 3 cm the effect disappeared into the noise. So the listing does not say "EMF".

Where we were wrong

Our first trigger fired on a statistical score alone. On a simulated phone lying still it produced 166 words in 5 minutes, more than the 151 it produced when something was actually happening. A z-score divides by the spread it has just measured, so the sensor was talking to itself. The detector now needs three things: an absolute floor in physical units, a threshold derived from a false-alarm budget rather than picked by hand, and persistence over 5 consecutive samples.

In one session we reported "64/64 checks pass" several times. One check had a ceiling of 250 while the scenario produced between 249 and 256, so it failed about 6 runs in 10, because the harness used an unseeded generator. Every generator is now seeded, and checks run on several fixed seeds and print their spread.

The Romanian word bank had been written without diacritics, and it was delivering different words: without accents, the word for "face" reads as "girl", and "river" and "bad" become the same word. We corrected 528 entries.

What the method does not guarantee

It does not tell us that Null Field will pass review or sell. It has never been submitted, so we have no review outcome to report. The scanner cannot see revenue or downloads, because Apple does not publish them, and reviews are somewhere between 0.3% and 5% of installs, so any estimate of installs spans a band of about 16 times. We implement 5 of the 10 NIST estimators, so the entropy figure the app shows is an upper bound, and the app says so.

Checklist

Before code. Scan for monthly flow, not lifetime ratings; filter search results by membership; discount price complaints; rule out free canonical tools and unfixable complaints; check the name against existing trademarks and Guideline 4.1.

While building. Keep the engine in a package with a readable, seeded verification suite; judge speed in release builds; check the built bundle, not the exit code.

Before submission. Run a clean install on the simulator; take screenshots from replayed real data; start the app in each language and look; ask for permissions at the point of use; confirm thresholds on hardware; keep the privacy and support URLs live and stable; run the release review.

Questions and answers

How do you test demand for an iPhone app idea before building it?

Testing demand for an iPhone app idea means scanning the App Store with Apple's public endpoints and deriving a monthly review rate from dated reviews, rather than trusting lifetime rating counts. One niche had a leader with 3,774 ratings yet produced 10 reviews a month across every app in it, so the niche was dead. Search results should be filtered so an app counts only if every query word appears in its name or description, and price complaints should not be read as demand.

What makes an App Store niche not worth entering?

An App Store niche is not worth entering when a free canonical tool already exists, whether preinstalled or funded by a university or a community. A niche is also ruled out when its top complaint cannot be fixed, such as metal detectors, where the magnetometer cannot see gold, silver or copper. Guideline 4.3 adds a third barrier, because Apple rejects near-duplicate apps from the same developer. App names should also be checked against existing trademarks and Guideline 4.1.

How can you test an iOS app's core logic without Xcode?

Testing an iOS app's core logic without Xcode works when the engine lives in a Swift package that depends only on Foundation and CryptoKit, with no UIKit and no CoreMotion. The command-line tools ship neither XCTest nor Swift Testing, so the tests can be an executable target that prints a readable comparison table. In one project that suite caught 4 real bugs that reading the code had missed. Speed should be judged only in release builds.

Why should you test an iPhone app on a clean simulator install before submitting?

A clean simulator install shows an iPhone app the way an App Store reviewer will see it. In one case the app requested the microphone at launch, but the developers' own phone had granted permission months earlier, so the prompt never appeared there. On a clean install the prompt did appear, which would have failed Guideline 5.1.1, since permission must be requested at the point of use. The iPhone 16 Pro Max simulator also produces 1320×2868 screenshots natively.

Why do sensor thresholds need to be measured on a real phone?

Sensor thresholds set on simulation need confirming on real hardware, because some effects appear only there. A field probe left on a table for 10 minutes reports the real sample rate, the noise and the number of false triggers. In one test the magnetometer noise matched the simulation, but the raw gyroscope showed a bias of 0.0168 rad/s at rest, above the textbook threshold, so a motion gate on raw data would never have opened. Bias-corrected rotation rate fixed the problem.

Is an iPhone app ready for the App Store once the build and checks pass?

Passing builds and checks does not mean an iPhone app is on the App Store or will pass review. In the worked example the app has a validated Release archive and a verification suite of 92 checks that passes, yet the app has not been submitted, because the paid Apple Developer Program membership was postponed on purpose. Without a submission there is no review outcome to report, and the method cannot predict whether the app will pass review or sell.

How to cite this

Going Stellar (2026). How we build an iPhone app. GOING STELLAR S.R.L..
https://goingstellar.ro/methods/how-we-build-an-iphone-app/

Read as Markdown

All methods

Contact

Tell us what is not working

Write in English or Romanian. A person reads it — usually the same person who would do the work — and answers within one business day.