◉RORK LABJP
●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SONNET 4.5 — Retires on the Claude API on 11/30, 26 days left. If your app calls it, check the migration target●SDK 58 — Moves to React Native 0.88. R8 is now on by default in Android release builds, and iOS prebuild generates a SceneDelegate●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SONNET 4.5 — Retires on the Claude API on 11/30, 26 days left. If your app calls it, check the migration target●SDK 58 — Moves to React Native 0.88. R8 is now on by default in Android release builds, and iOS prebuild generates a SceneDelegate●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…
Articles/Dev Tools
⬡ Dev Tools/2026-06-21Intermediate

Reclaiming the Pre-Submit Checks You Lose When Publishing Without Xcode

Rork Max's two-click publishing skips the Xcode Organizer, making it easy to miss usage strings, version bumps, and Bundle IDs. Here is a quick pre-submit self-audit you can run yourself, with how to read the generated files.

Rork612Rork Max235Info.plist8Indie Development31Release5

The first time I used Rork Max's two-click publishing, the convenience came with a slight unease. The step where I used to open the archive in Xcode's Organizer and eyeball the contents before submitting was gone entirely. Submission got faster, but with it vanished my chance to confirm "what I just sent."

Most of those skipped checks existed to prevent oversights rather than bugs. A single missing usage string, a forgotten version bump, a Bundle ID left over from a previous app. In the Xcode era, these small drifts would catch my eye before submission. Two-click does not pass through there, so you need to reclaim the self-audit as your own step. This time I will lay out a short pre-submit self-audit, along with where to look in the generated artifacts.

Why noticing after submission costs more

What makes oversights dangerous is that the build succeeds. It compiles, the two-click submit completes, and on the surface nothing looks wrong. It snags hours later at review, or worst case in a user report after release. The longer the distance from submission to discovery, the more the fix round-trip swells.

In my sense, spending a few minutes on a pre-submit self-audit pays for itself if it prevents even one review-rejection wait. Missing usage strings in particular are easy to fail review on, and they are exactly the kind of mistake you can detect mechanically before submitting. The trick is refusing to begrudge the last few minutes.

Are all the usage strings present

iOS requires a string explaining why you use a device capability—camera, location, and so on (a Purpose String). If the config Rork generates lacks this string while the feature is implemented, the app crashes at runtime or gets flagged at review.

Before submitting, check that the features you use and their usage strings line up one to one. For Expo-based Rork, check the config file; for Swift-native Rork Max, check the Info.plist.

# List usage-string keys from the Rork (Expo) generated config
# Look at both app.json and app.config.* to be safe
grep -REo 'NS[A-Za-z]+UsageDescription' app.json app.config.* ios/ 2>/dev/null | sort -u
 
# For Rork Max (Swift), read the Info.plist directly
plutil -p ios/*/Info.plist 2>/dev/null | grep -i "UsageDescription"

Match the listed keys against the capabilities your app actually uses. For example, if you save photos but NSPhotoLibraryAddUsageDescription is absent, that is a hole. I make a habit of adding the matching string whenever I add a feature, yet I still print this list once right before release and look at it. Implementation and config live in separate files, so one moving without the other is bound to happen.

Misplaced version and Bundle ID

What grows when you ship your second app and beyond is leaving the version unchanged and reusing the Bundle ID. With Xcode's Organizer the version showed large on the submit screen, so you noticed; with two-click it is easy to miss in the flow.

There are two things to check: the display version (the number users see) and the build number (the internal number you increment within a version). App Store Connect will not accept a resubmission with the same build number.

# Check the display version and build number at once
# Expo: version and ios.buildNumber in app.json
grep -E '"version"|"buildNumber"' app.json
 
# Swift native: CFBundleShortVersionString and CFBundleVersion in Info.plist
plutil -p ios/*/Info.plist 2>/dev/null | grep -E "CFBundleShortVersionString|CFBundleVersion|CFBundleIdentifier"

The Bundle ID is where the previous app's value tends to linger when you base a project on a template or a past project. As an indie developer, when I built similarly structured apps back to back, the Bundle ID stayed as the previous one and the submission stalled against the App Store Connect registration. Before submitting, always look once to confirm this is a value unique to this app.

Fold the self-audit into one command

Typing these by hand every time means you skip them exactly when you are busy. I fold the pre-submit checks into a single script and always run it before pressing publish.

#!/usr/bin/env bash
# presubmit-check.sh — mechanically check the minimum before publishing
set -euo pipefail
 
echo "== Usage strings =="
grep -REo 'NS[A-Za-z]+UsageDescription' app.json app.config.* ios/ 2>/dev/null | sort -u \
  || echo "(config not found; check the path)"
 
echo "== Version / Bundle ID =="
grep -E '"version"|"buildNumber"' app.json 2>/dev/null || true
plutil -p ios/*/Info.plist 2>/dev/null \
  | grep -E "CFBundleShortVersionString|CFBundleVersion|CFBundleIdentifier" || true
 
echo "== Checklist =="
echo "[ ] usage strings present for every capability used"
echo "[ ] display version bumped from last time"
echo "[ ] Bundle ID is unique to this app"

The benefit of a script is that the audit drops out of the "do it / skip it" decision. Once it is part of the publish flow, you do not miss it even in a hurry. Even running several apps in parallel at Dolice Labs, I share this one script across all of them, so audit quality stays consistent even on a new app.

What two-click publishing removed is the effort, not the need to verify. Reclaim the eyeballing you lost as a mechanical self-audit on your side. Before your next Rork Max release, try printing the usage-string list once. Just knowing there are no holes should lighten the hand that presses publish.

Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⬡ Dev Tools2026-10-27
Claude Sonnet 4.5 Leaves the API on November 30. Find the Model IDs Hard-Coded in Your App First
Claude Sonnet 4.5 is scheduled to retire from the API on November 30, 2026. A small script finds the model IDs written into your app's code and config, so you can replace them and check again.
⬡ Dev Tools2026-08-21
The four acceptance checks I still run after the build turns green
A successful build does not mean a shippable build. Here are the four failure classes an AI build loop cannot see, and a dependency-free script that inspects the artifact itself before you submit.
⬡ Dev Tools2026-05-18
Fixing Linking.canOpenURL False Returns on iOS in Rork
Production iOS builds silently route every user to the mobile web instead of opening TikTok or X? This is almost always a missing LSApplicationQueriesSchemes entry. Here is the full fix path for Rork.