Welcome, and thank you for your interest in translating VOCR! This guide will help you localize VOCR into your language, whether or not you have access to Xcode.
VOCR is an accessibility application for macOS that provides OCR and AI-powered screen recognition. Making it available in multiple languages helps users worldwide access their computers more effectively.
Choose the method that works best for you:
| Method | Requirements | Difficulty | Best For |
|---|---|---|---|
| Xcode | Mac with Xcode 15+ | Easy | macOS developers |
| Manual | Text editor | Medium | Anyone |
This is the easiest method if you have access to a Mac with Xcode.
# Clone the repository
git clone https://github.com/chigkim/VOCR.git
cd VOCR
# Switch to the localization branch
git checkout localization
# Open in Xcode
open VOCR.xcodeproj
Localizable.xcstringsInfoPlist.xcstringsare checked
Localizable.xcstringsTips:
%@ and %d (see below)InfoPlist.xcstringsIf the Main.storyboard is localizable:
Main.storyboard in the Project Navigator.strings file for your languageOption A: Commit to Git (if you have permission)
git add VOCR/Localizable.xcstrings VOCR/InfoPlist.xcstrings
git commit -m "Add [Your Language] translation"
git push origin localization
Option B: Export as .xcloc (recommended for contributors)
.xcloc bundle you can send to the maintainersIf you don’t have access to Xcode, you can still translate by editing the .xcstrings files directly.
String catalog files (.xcstrings) are JSON files with this structure:
{
"sourceLanguage" : "en",
"strings" : {
"menu.settings.targetWindow" : {
"comment" : "Menu item for selecting target window",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Target Window"
}
}
}
}
},
"version" : "1.0"
}
# Clone the repository
git clone https://github.com/chigkim/VOCR.git
cd VOCR
# Switch to the localization branch
git checkout localization
Or download the branch as a ZIP from GitHub.
First, determine your language code. Common codes:
esfrdejazh-Hanszh-Hantpt-BR (Brazil) or pt-PT (Portugal)itkoarruOpen VOCR/Localizable.xcstrings in your text editor.
For each string entry, add your language translation:
"menu.settings.targetWindow" : {
"comment" : "Menu item for selecting target window",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Target Window"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ventana de Destino"
}
}
}
}
Important JSON Rules:
"menu.settings.targetWindow")"comment" fieldOpen VOCR/InfoPlist.xcstrings and translate the 3 permission strings:
{
"sourceLanguage" : "en",
"strings" : {
"NSCameraUsageDescription" : {
"comment" : "Permission description for camera access",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Capture a photo to VOCR to use."
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Capturar una foto para usar en VOCR."
}
}
}
}
},
"version" : "1.0"
}
Option A: Use an online JSON validator
Option B: Use command line (if you have Python)
python3 -m json.tool VOCR/Localizable.xcstrings > /dev/null
If there are no errors, your JSON is valid.
If you want to translate the storyboard menu items:
VOCR/[YourLanguageCode].lproj/
VOCR/es.lproj/ for SpanishCopy VOCR/Base.lproj/Main.storyboard to your folder
Option A: Create a Pull Request (recommended)
# Create a new branch for your translation
git checkout -b translation-[language]
# Add your changes
git add VOCR/Localizable.xcstrings VOCR/InfoPlist.xcstrings
# Commit
git commit -m "Add [Your Language] translation"
# Push and create pull request
git push origin translation-[language]
Option B: Send Files to Maintainers
.xcstrings files to the project maintainersKeys follow a hierarchical naming pattern:
| Prefix | Usage | Example |
|---|---|---|
menu.* |
Menu items | menu.settings.autoScan |
button.* |
Button labels | button.save, button.cancel |
dialog.* |
Dialog text | dialog.reset.title |
error.* |
Error messages | error.connection.title |
alert.* |
Alert messages | alert.asking.message |
navigation.* |
Navigation status | navigation.finished_scanning |
shortcut.* |
Keyboard shortcuts | shortcut.ocr_window |
Some strings contain format specifiers that will be replaced with values at runtime:
| Specifier | Meaning | Example |
|---|---|---|
%@ |
String | "Asking %@" → "Asking GPT-4" |
%d |
Integer | "Status code %d" → "Status code 404" |
%% |
Literal % | "100%%" → "100%" |
Important Rules:
%@ to %d or vice versaExamples:
✅ Good:
"en": "Finished scanning %@, %@"
"es": "Escaneo completado %@, %@"
"ja": "%@、%@ のスキャンが完了しました"
❌ Bad:
"es": "Escaneo completado" // Missing format specifiers!
"ja": "スキャンが完了しました %d, %d" // Wrong type (%d instead of %@)
For strings with multiple %@, they’re replaced in order. If your language needs a different order, you can use positional specifiers:
"en": "Finished scanning %@, %@" // App name, window name
"ar": "انتهى المسح %2$@, %1$@" // Reversed order for Arabic
Where %1$@ refers to the first parameter and %2$@ to the second.
Always read the comment field to understand where and how the string is used:
"comment" : "Menu item for selecting target window"
This tells you:
Remember that VOCR is an accessibility application. Many strings will be:
Maintain consistency for these technical terms:
| English | Keep consistent in your language |
|---|---|
| OCR | May stay as “OCR” or translate to your language |
| VoiceOver | Usually stays “VoiceOver” (Apple product name) |
| Scan/Scanning | Use consistent verb form |
| Window | GUI window (not glass window!) |
| Preset | Saved configuration/template |
| Shortcut | Keyboard shortcut |
If your translation is much longer, consider:
// Short, action-oriented, often with hotkey
"menu.settings.autoScan": "Auto Scan"
"menu.saveLatestImage": "Save Latest Image"
"menu.quit": "Quit"
// Longer, informative, complete sentences
"dialog.reset.message": "This will erase all the settings and presets. This cannot be undone."
"dialog.soundOutput.message": "Choose an Output for positional audio feedback."
// Very short, imperative
"button.save": "Save"
"button.cancel": "Cancel"
"button.create": "Create"
// Clear, helpful, not blaming the user
"error.connection.title": "Connection error"
"error.http.message": "Status code %d: %@"
"error.nodata.message": "No data received from server."
// Natural language, as if speaking to user
"navigation.finished_scanning": "Finished scanning %@, %@"
"message.realtime_ocr_started": "RealTime OCR started."
"app.ready": "VOCR Ready!"
If you use VoiceOver or can test with it:
Make sure your translation doesn’t break functionality:
Checklist:
Localizable.xcstrings are translatedInfoPlist.xcstrings are translated%@, %d) are preservedgit checkout -b translation-[language]git commit -m "Add [Language] translation by [Your Name]"git push origin translation-[language].xcstrings filesContact the project maintainers (check README for contact info) with:
.xcstrings filesYour contribution will be acknowledged in:
Please let us know how you’d like to be credited!
A: Machine translation (Google Translate, DeepL, etc.) can be a starting point, but you must review and correct the output. Machine translations often:
Always review and edit machine translations to ensure they’re natural and accurate.
A:
.xcstrings fileA: Partial translations are better than none! However:
A: Generally, use the form that’s most appropriate for:
Consistency is key—choose one form and stick with it throughout.
A: Yes! Translation is an ongoing process. You can:
A:
A: Always use UTF-8 encoding. Most modern text editors use this by default. This ensures characters from your language display correctly.
A: Absolutely!
Your contribution makes VOCR accessible to more people around the world. Thank you for taking the time to translate!
If you have any questions not covered in this guide, please:
We’re here to help and appreciate your efforts! 🌍🎉
Last Updated: January 28, 2026
VOCR Version: 2.3.1
Localization Branch: localization