It was Friday night. I was out with classmates after class, drinks at a bar, the kind of after-week wind-down where you're not expecting anything important to happen. My phone rang. Caller ID said Apple. I was in the middle of a busy bar and didn't want to pick up, and honestly part of me was skeptical too. Apple calling me directly seemed like the kind of thing a scam might pretend to be.
I let it go to voicemail.
When I checked later, the auto-transcription Apple does on incoming voicemails gave me the gist. A member of Apple's App Review team said he wanted to talk about WhisperPad. He didn't say why. I tried to call back at 9:30 Barcelona time and it was already after his working hours in Pacific. I told my classmates Apple was calling me. It felt unreal. Apple is giving me a phone call. That was the framing in my head all weekend.
The wait
I had a long weekend ahead of me wondering what the call was about. I let myself hope it was a reversal. I'd been very public about the original rejection. Part of me was nervous Apple might be calling for a different reason. Maybe they wanted to communicate something firm in private rather than in writing.
The call
On Monday I was in class. They called during a break. I picked up.
The conversation was three or four minutes. The Apple reviewer was calm and friendly. He told me the App Review board had taken a closer look at my original rejection and decided to reverse it. WhisperPad's use of the Accessibility API was approved. I could resubmit the version they'd previously rejected, using the same method, and reference our conversation in the review notes.
He said: "Sometimes a single reviewer's call gets revisited by the board, and the decision flips." I thanked him for his time. End of call.
What I felt
Mostly confused, then thankful. I'd been operating for two weeks on the assumption that this path was permanently closed. I'd forked the app into two separate SKUs. I'd stood up direct distribution with Paddle for payments and Sparkle for updates. I'd written architectural decision records explaining why the fork was permanent. And now, with one phone call, all of that had changed.
Ultimately, I'm happy Apple reached out. They approved the app. I'm stoked about it. The story is closed in the best possible way.
The work of un-doing the fork
The reversal sounded simple on the phone. Resubmit the version you originally built. In code, it was anything but simple.
When I split WhisperPad into two versions in May, I'd guarded the differences behind a compile flag called MAS_BUILD. The flag had quietly come to mean two unrelated things. One: legitimate, permanent exclusions required by the App Store sandbox, like the in-app crash reporter that reads files the sandbox blocks. Two: feature reduction to dodge the 2.4.5 rejection — the clipboard-only paste path, the disabled transcription modes, the abbreviated onboarding. With the reversal, I needed to keep the first kind and undo the second.
Restoring the full app meant unwinding MAS_BUILD guards across seven files. Core insertion logic. App startup permissions. Settings UI. The onboarding flow. The FAQ. The result panel. Most of the work was deleting code. The compliance changes had added complexity, and the reversal removed it.
Net result: forty-four lines fewer than before.
The Sparkle dance
The trickier piece was the auto-updater. Sparkle, the long-standing framework that handles updates for non-App-Store Mac apps, ships helper executables that are incompatible with the sandbox by design. The sandbox exists to keep apps from escaping into the rest of the system. Sparkle's whole job is to escape and replace the parent app. The App Store will reject any bundle that contains a non-sandboxed executable.
So Sparkle has been toggled in and out of the codebase four times in two weeks. Out for the compliant 1.7. Back in for the direct launch. Out again on Monday, briefly, because the moment I tried to upload the 1.8 App Store build the validation failed with the exact error from before — Sparkle's helpers were back in the bundle because Sparkle is linked as a Swift Package and embeds automatically. Restored immediately after the MAS upload cleared.
That dance is fragile and manual. The permanent fix is conditional framework linking or revisiting the single-target decision, both of which are on the list. For now, git is the safety net.
What this means for the studio
The direct-distribution channel from mitmllc.com still exists. I'm keeping it. People who want to save the App Store markup can buy direct. People who want Apple's trusted purchase flow can buy from the App Store. The same product, two channels, neither one a compromise.
Without the original rejection, I never would have built the direct channel. Sometimes the workaround you're forced to build becomes the thing you're glad you have. I learned a lot in two weeks I wouldn't have learned in two months of straight App Store work. The infrastructure I now have for direct distribution will outlast WhisperPad. It's there for whatever I ship next under MITM LLC.
What I'd say to other developers
Build your own distribution channel anyway. Not because it'll force Apple to reverse a rejection ...though, hey, maybe it will, who knows. Build it because it's an asset you'll want to have regardless. And triple-check your work when you do. The biggest headache I had during the launch wasn't anything Apple did. It was that some users downloaded a version with a broken auto-updater and a stale purchase link, and they couldn't get to my payment page. That cost me real customers and a lot of email apologies. Sparkle, entitlements, license-key delivery etc.
Closing
Overall I'm thankful this saga happened. I made real connections answering emails from customers, from people reaching out about RSI in general, from other Mac developers who'd hit the same wall. It was good to see those connections form and to talk with people dealing with similar issues. I learned a lot.
It's been an interesting two weeks. Super hectic, super fun, and all of it on top of writing a master's thesis and building my final presentation. June is going to be a busy month.
WhisperPad is now what it was always supposed to be, in both places it was supposed to be. The loop is closed.
If you want to try it, the direct version is at mitmllc.com/whisperpad. The Mac App Store version is also live with the full auto-paste functionality now. The free tier is 120 minutes a month either way. If you want to write to me here: contact@mitmllc.com
This post was dictated using WhisperPad.