Psiphon iOS VPN Client.
Prerequisites
- Cocoapods
sudo gem install cocoapods
Building
- Replace
Shared/psiphon_config.stub
with your configuration file. - Replace
Shared/embedded_server_entries.stub
with your server entries file. - Replace
Psiphon/Bourbon-Oblique.otf
with the "Psiphon" font file. - Run
pod install
to install the third-party libraries.
I18n/L10n
Adding or modifying strings
All user-facing strings must be localized; logs and strings not visible to users should not be.
...in an Objective-C file
When adding a string, use this function:
NSLocalizedStringWithDefaultValue(<key>, nil, [NSBundle mainBundle], <string>, <description>)
<string>
is the actual string shown to the user (in English). <description>
is a description and of and context for the string to help translators correctly localize it.
<key>
must be in an ALL_CAPS
form,
and not just the string itself. This allows us to change or fix the
string without changing its key, thereby allowing us to not lose
existing translations just because we fix a typo in the English (for
example).
So, when making a minor edit to a string that does not fundamentally change its meaning, do not change the key. When making a major edit that should invalidate existing translations, also change the key. Do not be precious about existing translations: if meaning changes, change the key -- the translations will catch up.
After adding or modifying a string, build the project, that will trigger genstrings.sh
, which will update en.lproj/Localizable.strings
. Commit that file with your change and Transifex will automatically pick up the change (overnight).
...in a .plist
file
There are three .plist
files in this project (all under Psiphon/InAppSettings.bundle
). They are all based on similar files in the PsiphonClientCommonLibrary project.
Root.inApp.plist
: The root of -- and majority of -- the settings.ConnectionHelp.plist
: Settings specifically broken out to help with connection problems.Feedback.plist
: The feedback interface.
Many of the strings in those files are translated in PsiphonClientCommonLibrary, and so they should directly reference that bundle. Like so:
<key>BundleTable</key>
<string>PsiphonClientCommonLibrary</string>
For items and strings not in PsiphonClientCommonLibrary: When adding or modifying strings, you must reflect the changes in [en.lproj/Root.strings
][Root.strings]. Use the ALL_CAPS
form described above for the key (yes, that means that the plists will
be full of non-English keys), as well as the minor/major edit
considerations for changing a key. Provide a comment in Root.strings
for every entry -- this is the description/context for translators.
Also, make sure you implement required methods when adding a new specifier of IASKCustomViewSpecifier
type, see InAppSettingsKit README.
Updating translations
Translations for this project are in two places: in PsiphonClientCommonLibrary and in this project. The former has the settings and feedback strings common to all Psiphon iOS apps. The latter has the strings specific to this app.
Updating the PsiphonClientCommonLibrary strings involves updating the pod for that library in this project. You can run pod update PsiphonClientCommonLibrary
or modify the target commit hash in the Podfile
and then run pod install
. (Instructions for how to update the strings in PsiphonClientCommonLibrary can be found in that project's README.)
To update the strings in this app, run ./transifex_pull.py
from the project root (with a valid transifex_conf.json
in place). git status
will show you which languages changed. Do some smoke tests on those languages and commit.
While running transifex_pull.py
you may see some output like this:
Resource: ios-vpn-app-localizablestrings
Skipping language "uz" with 56% translation (13 of 23)
This indicates that there is a well-translated language that is currently not part of the pull (and not part of the currently supported languages). You may wish to consider adding this language. See the next section for instructions how.
Adding a new language
As mentioned above, translations for this project are in two places: in PsiphonClientCommonLibrary and in this project. The former has the settings and feedback strings common to all Psiphon iOS apps. The latter has the strings specific to this app. Adding a new language requires updating both projects.
To learn about adding a new language to PsiphonClientCommonLibrary, see the README for that project. When it is updated, update its pod in this project (see above for instructions).
To add a language to this project, follow these steps:
-
Add the language to the Xcode project. In the Project settings, Info tab. Click
+
and select the desired language. (If it's not in the list, then it can't be added here. It isn't supported natively by iOS, but it can still be added and selected from the app settings. Skip to step 2.) Allow it to createLocalizable.strings
, but notLaunchScreen.storyboard
. (If you had already pulled the translation, you'll need to re-pull, since this will clobber it.) Make note of the language code used by Xcode. If this differs from the code used by Transifex, there will need to be a mapping between them in the next step. You should see thatShared/Strings/<new-language>.lproj/Localizable.strings
has been created. -
Add the language to
transifex_pull.py
. At the top oftransifex_pull.py
is a dict containing all supported languages. It is a map from the Transifex locale codes to the iOS locale codes. Add the new language to this dict, in alphabetical order, with the correct mapping (noted in the previous step). -
Run
transifex_pull.py
. This will pull all translations, including the newly added one. You should see thatShared/Strings/<new-language>.lproj/Localizable.strings
has been updated (translated) and thatStoreAssets/<new-language>.yaml
has been created. -
Add the language to our in-app language selector. In
Psiphon/InAppSettings.bundle/Root.inApp.plist
, add the new language code and the name of the language as it's written in that language. If the language is not one of our top 3 or 4, it should be added in alphabetical order, based on the language code. Note that if the language was first added to PsiphonClientCommonLibrary, then the name will be (should be) available in that project'sRoot.inApp.plist
. (Otherwise check the Omniglot list.)
Do some testing. Commit.
Using App Store assets
The App Store listing for this app requires an app name, subtitle,
description, keywords, etc. These should be localized. These English
values for these strings are contained in StoreAssets/master.yaml
. These values must be kept up to date with the values in iTunes Connect.
When transifex_pull.py
is run, the translations for these values will be updated.
Adding a language for the listing is pretty obvious in iTunes Connect. As is switching between languages to modify them.
Note that the App Store does not support all the languages supported by apps -- the options you see available are all that there are. Notably, Arabic and Farsi are not supported. We may wish to append those languages to the bottom of the English description (as an example, see the Psiphon Browser listing).
To update translations in iTunes Connect, switch between the
languages in the web interface and paste in the corresponding
translation from StoreAssets/<language>.yaml
. Remember to de-indent the description.
Acknowledgements
Psiphon iOS VPN client uses:
from https://github.com/Psiphon-Inc/psiphon-ios-vpn
No comments:
Post a Comment