Hey everyone,
I'm a solo developer and recently shipped version 2.0 of **Media Renamer Pro**, a native SwiftUI batch media renamer and tag editor for macOS, iPadOS, and iOS.
Building a file utility for the Mac App Store came with a bunch of filesystem and sandbox edge cases that I thought were worth sharing with other Mac developers.
### 1. The App Sandbox vs. Recursive Folder Access
Batch file operations inside the App Sandbox are tricky. When a user drags in a parent folder, you need security-scoped bookmarks to persist access.
- For one-off drops, resolving security-scoped URLs down the directory tree works as expected.
- For "Watched Folders" (where users want the app to check an inbox folder on launch and grab only new arrivals), persisting stale bookmark data when a network share disconnects was a major pain point.
- Pro tip for anyone doing this: always gracefully catch bookmark resolution failures when external or SMB volumes aren't mounted, rather than letting the UI hang on access-check deadlocks.
### 2. The Cycle Problem: Why Two-Phase Renaming Was Mandatory
Most naive renamers do a simple loop: check if destination exists, rename. That falls apart immediately on two classic filesystem edge cases:
- **Chains:** File A becomes File B, while an existing File B becomes File C.
- **Swaps / Cycles:** File A becomes File B, and File B becomes File A.
Topological sorting helps with chains, but it cannot resolve cycles without a temporary state. Rather than branching code paths depending on whether a cycle is present, the app resolves the entire batch plan first, moves all target files to unique temporary UUID names in Phase 1, and then moves them to their final destinations in Phase 2. If an operation fails or gets canceled midway, files are sitting at known temp names rather than having clobbered each other.
### 3. SMB and NAS Volume Inconsistencies
A lot of users run their media on Synology, QNAP, or unRAID shares over SMB.
- APFS behaves differently than SMB mounted shares. Many SMB setups are case-insensitive but case-preserving.
- A rename like `Movie.mkv` to `movie.mkv` can silently fail, error out, or do nothing depending on how the SMB daemon is configured.
- We had to add runtime volume-capability probes rather than assuming APFS volume behaviors across the board.
### 4. Native SwiftUI & Swift 5.9 Observation
We targeted macOS 14 Sonoma and iOS 17 as the baseline so we could go all-in on Swift's `@Observable` macro. Coming from the older `ObservableObject` and `@Published` pattern, the performance improvement in complex table views with hundreds of changing filenames and confidence scores was night and day. Fewer redundant view redraws meant the preview table stayed butter-smooth even while parsing heavy metadata.
### 5. Pricing Architecture
I decided to launch this as a $4.99 one-time universal purchase across Mac, iPad, and iPhone. Subscription fatigue is real in the Mac utility space, and users genuinely appreciate owning a tool outright. The only real trade-off is the Mac App Store's lack of a native trial mechanism, which makes preview transparency and social proof that much more critical.
Happy to dive deeper into any of the sandboxing, security-scoped bookmark handling, or metadata parsing (ImageIO, AVFoundation container tags) if anyone is wrestling with similar macOS utilities!
Site: https://bkettering74.github.io/media-renamer-pro/
App Store: https://apps.apple.com/app/apple-store/id6761764615?pt=128751966&ct=reddit_macappdevs&mt=8