RORK LABJP
SDK58 — The Expo SDK 58 beta is open. It ships the React Native 0.88 release candidate, and the beta period is stated as three to four weeks11/01 — For anyone who requested an extension, Google Play's target API deadline lands on November 1. Forty-four days outEASENV — A long-open report: secrets handed to a local build arrive as the literal variable name rather than its value, and the damage surfaces much laterNEW — The replacement the table recommended had already shut down. A record of reconciling all 74 rows of the deprecation listUISCENE — iOS 27 requires the new scene lifecycle. SDK 57 makes it something you opt into; it only becomes the default in 58CREDIT — What "AI errors don't cost credits" actually covers becomes clear once you record a day of asking for the same fix more than onceSDK58 — The Expo SDK 58 beta is open. It ships the React Native 0.88 release candidate, and the beta period is stated as three to four weeks11/01 — For anyone who requested an extension, Google Play's target API deadline lands on November 1. Forty-four days outEASENV — A long-open report: secrets handed to a local build arrive as the literal variable name rather than its value, and the damage surfaces much laterNEW — The replacement the table recommended had already shut down. A record of reconciling all 74 rows of the deprecation listUISCENE — iOS 27 requires the new scene lifecycle. SDK 57 makes it something you opt into; it only becomes the default in 58CREDIT — What "AI errors don't cost credits" actually covers becomes clear once you record a day of asking for the same fix more than once
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.

Rork569Rork Max234Info.plist6Indie Development26Release4

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 $15 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-07-10
The Termination That Never Shows Up as a Crash — Reading JetsamEvent in Rork Apps
Crashlytics is silent, yet reviewers write that the app closes by itself. Most of the time the OS killed it for exceeding its memory limit. Here is how to read JetsamEvent reports and design an image-heavy app's memory budget from measured values.
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-07-17
The Update That Failed Because a Profile Expired Three Months Ago
Apple signing assets expire quietly and nothing tells you. Here is how to count the days left with the App Store Connect API and put the audit on a weekly Cloudflare Workers cron.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links