ANTIGRAVITY LABJP
Articles/App Development
App Development/2026-05-20Intermediate

Two Weeks of Letting Antigravity Translate Localizable.xcstrings Across 8 Languages

A two-week log of letting Antigravity draft 8-language translations for new keys added to Localizable.xcstrings. What I delegated, what I kept under my own judgment, the unexpected behaviors, and how I reconciled drafts against the existing translation corpus.

antigravity435xcstringslocalization6ios36app-dev49swift9

One Tuesday afternoon in May 2026, the new feature I had just added to one of my iOS wallpaper apps left another set of strings waiting for translation across eight languages. Opening Localizable.xcstrings showed a row of empty cells stretching across English, Simplified Chinese, Traditional Chinese, Korean, Spanish, French, German, and Portuguese — each waiting to be filled in. A typical release adds 8–12 new keys, and once you multiply that by eight languages, an hour disappears before you realize.

I have been shipping iOS apps on my own since 2014, and the wallpaper, calm, and inspiration apps I run have grown to a combined 50 million downloads. International users make up a large share of that base. English speakers dominate, of course, but reviews from Germany, Brazil, and Taiwan reach me every week. Because of that, I have always wanted to avoid leaving localization in a purely mechanical state — the wording should feel natural in each language.

Two weeks ago I started letting Antigravity handle the first pass. Full automation was never the goal. I wanted to move from "filling each cell of the xcstrings editor by hand" to "letting the AI draft, and stepping in only for final adjustments." Here are the workflow that settled in, the unexpected behaviors I ran into, and what I noticed once existing translations were brought into the loop.

Why I started — separating the "mechanical" part from the "judgment" part

A mentor I met online when I was 17 once told me that art is a natural language open to everyone. That memory comes back every time I work on localization. Even a single string in an app should reach speakers of that language naturally — otherwise I have not really put that lesson into practice.

That said, deciding whether "Continue" should be "Fortsetzen" or "Weiter", or how to say "You're all set" naturally in Korean, from scratch each time, feels closer to dictionary lookup than to judgment. If you simply remembered the phrasing from past releases or Apple's guidelines, the choice would take a second. Instead, every release was a slow re-derivation. That repetition started feeling like the "mechanical" part to me earlier this spring.

Both of my grandfathers were temple carpenters in Japan, and I have always resisted the idea of treating handwork lightly. But those grandfathers separated marking out the wood from the carving — two different rhythms, two different concentrations. I was the one mixing the two together.

What I delegated and what I kept

The first thing I decided was where to draw the line for Antigravity. Localizable.xcstrings is a JSON-based file, so Antigravity can read and write it directly. But handing everything to the AI would risk drift from the phrasing I had used in prior releases. So I split it like this.

  • Delegated to the AI: first-pass translation for newly added keys across all 8 languages, generation of context comments, lookups for similar prior keys to keep phrasing consistent, and flipping state to translated inside the xcstrings file.
  • Kept under my final judgment: brand-flavored strings (app names, mode names, paid feature names), any alert wording that App Review tends to scrutinize, final approval of every first draft, and release-notes translation.
  • Shared between us: cases where a new draft conflicts in nuance with an existing translation — whether to follow precedent or rephrase both.

In short, I let the AI handle the draft and the consistency check, while the final string that ships to users stays with me. The boundary shifted a few times in the first few days but settled by the middle of the second week.

The workflow that emerged after two weeks

The routine runs whenever I add new keys.

  1. In Xcode, I add the new keys to Localizable.xcstrings and finalize the English source.
  2. In Antigravity's chat, I drop the xcstrings file and say: "Translate only the new untranslated cells into the eight target languages. If similar phrasing exists in past keys, follow it."
  3. Antigravity reads the file, picks out keys whose state is new, and drafts translations for each language.
  4. When something might conflict with existing wording, Antigravity comes back asking: "Should this align with the phrasing in key XXX, or use a different one?"
  5. I reply with a direction, and Antigravity writes the diff back into the xcstrings file (still unstaged in git).
  6. I open the xcstrings editor in Xcode and review every generated cell visually, fixing only the ones that feel off.
  7. I build and run on a device to confirm there are no truncations or layout breaks, then commit.

On the first day, 8 keys × 8 languages — 64 cells in total — went from draft to final in about 20 minutes. By the second week the routine settled at 10–15 minutes. The same work used to take me 45–60 minutes, so the saved time goes straight back into actual implementation.

Unexpected behaviors and how I handled them

Not everything went smoothly. Three issues in particular are worth recording.

First, the handling of Plural Variations. Plural support in xcstrings is more organized than the older .stringsdict setup, but several languages need categories beyond one and otherzero, two, few, many. My first request to Antigravity left only other populated in Russian, leaving few empty. Once I added "if the target language requires the zero, two, few, or many categories, fill those in as well" to the prompt, the gaps disappeared.

Second, format specifiers like %@ and %lld. Antigravity rearranged %@ to fit the natural word order of each language, which was useful, but in a few early cases it rewrote %@ as %s. That fails at compile time, so it is not catastrophic, but catching it in CI is a frustrating timesink. I added "do not change format specifiers (%@, %lld, %.2f, etc.) — only their position may move to fit word order" and the issue went away.

Third, consistency checks against existing translations. This got better over time, but at first the AI could not decide what to do when a past release had translated the same concept inconsistently — "閉じる" versus "閉じる" versus "とじる" in Japanese, for example. I now keep a phrasing glossary at _documents/style_glossary.md for the project and have Antigravity reference it on every run. The drift has nearly disappeared.

Reconciling against existing translations

This took the most thought before going into the routine. Since Localizable.xcstrings itself functions as a database of past translations, I wanted the AI to check against precedent every time.

The implementation is simple: I paste the full xcstrings into every prompt sent to Antigravity. The context grows, but my xcstrings files sit between 3 and 8 KB across all four apps, so context pressure has not been an issue.

For the day when xcstrings inevitably grows larger, I have prepared a separate sub-agent in Antigravity's Workspace whose sole job is to look up related past keys and quote them. It barely fires today, but I expect to switch to it once any project crosses a few hundred keys.

What the recovered time has shown me

Net savings come out to roughly 30–40 minutes per round of new keys. With 4–6 releases a month, that totals 2–4 hours. That alone is not dramatic, but the bigger shift is that the time has eliminated my habit of postponing releases simply because localization had not caught up.

Before this, two or three times a month I would push a release back a week because "the feature is ready, but the translations are not." That rarely happens now. Once the feature is done, the release can ship the same day.

A side effect: the context comments inside the xcstrings file are now written with more care. I add them as background for the AI, and the result is that a future reader — quite often my future self — has an easier time. I sometimes think about my children, who live apart from me, and quietly hope that something of what I make reaches them someday. It turns out that "future reader" is also future me, and that has been a gentle realization.

What comes next

In the short term, I plan to add two or three more languages. Turkish and Arabic have started appearing more in recent reviews, and now that the drafting layer is in place, the addition feels less costly. Arabic will need an RTL layout pass, so the next two weeks will mostly be about splitting that work cleanly between Antigravity and myself.

Longer term, I want to apply the same pattern — AI drafts, human finalizes — to App Store Connect metadata: descriptions, keywords, screenshot captions. If the rhythm that worked for xcstrings carries over, another chunk of release time should come back.

I hope some of this is useful if you are working through multi-language support on your own apps. Thank you for reading along.

Share

Thank You for Reading

Antigravity 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

App Dev2026-06-15
Stop Adding a Ternary Every Time a New iPhone Ships: A Table-Driven Resolution Design
Every time a new resolution arrived—iPhone Air, 17 Pro—I was bolting another screen-size ternary onto a 29-branch pile. Here is how I reshaped that into a table-driven design where adding the next device is a one-line data change, with the actual Swift from my wallpaper apps.
App Dev2026-05-13
Implementing Google ML Kit with Antigravity: What the Docs Don't Tell You
A practical guide to integrating Google ML Kit into iOS and Android apps with Antigravity. Covers text recognition, face detection, the Xcode 15 SPM bug workaround, and honest notes on where AI assistance helps — and doesn't.
App Dev2026-04-05
How to Auto-Generate and Manage iOS Privacy Manifests with Antigravity
Auto-generate iOS Privacy Manifests with Antigravity. Scan Required Reason APIs, create PrivacyInfo.xcprivacy, and pass App Store review — step by step.
📚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
See all →