As of version 1.0.0 this pod adheres to Semantic Versioning 2.0.0
To run the example project, clone the repo, and run pod install
from the Example directory first. Then open PsiphonClientCommonLibrary.xcworkspace
in Xcode.
To install, simply add the following line to your Podfile:
pod 'PsiphonClientCommonLibrary', :git => "https://github.com/Psiphon-Inc/psiphon-ios-client-common-library.git"
Copy psiphon-ios-client-common-library/Example/PsiphonClientCommonLibrary/InAppSettings.bundle
into your project and customize it to fit the needs of the project it is being used in. You can find more information on how InAppSettingsKit works here.
Use PsiphonSettingsViewController
for displaying the shared settings menu. Subclass it to provide any functionality for new project specific settings.
cd ./Example
pod install
open PsiphonClientCommonLibrary.xcworkspace
Now you can start making changes to the pod by working with the files in Pods/Development Pods
in the Xcode project.
- In Xcode, under the Resources group, click on
Images.xcassets
. Note the assets list that appears. - In Finder, go to
psiphon-ios-client-common-library/External/flag-icon-css/flags/4x3
. Select the filesflag-zz.png
,[email protected]
, and[email protected]
, wherezz
is the region you want. - Drag the selected files onto the assets list in Xcode.
- In
RegionAdapter.m
, update theinit
andgetLocalizedRegionTitles
functions with the new region. - Compile the app, so that the strings files get updated.
After making any changes, to see the result in the Example app, go into the Example
directory and run pod update PsiphonClientCommonLibrary
.
The library version number must be incremented when a translation change is made.
All user-facing strings must be localized; logs and strings not visible to users should not be.
When adding a string to Objective-C, use this function:
NSLocalizedStringWithDefaultValue(<key>, nil, [PsiphonClientCommonLibraryHelpers commonLibraryBundle], <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.py
, which will update en.lproj/Localizable.strings
. Commit that file with your change and Transifex will automatically pick up the change (overnight).
There are three .plist
files in this project (all under Example/PsiphonClientCommonLibrary/InAppSettings.bundle
). They should be used as the basis for the plists in the app projects.
Root.inApp.plist
: The root of -- and majority of -- the settings.PsiphonSettings.plist
: More Psiphon-specific settings.ConnectionHelp.plist
: Settings specifically broken out to help with connection problems.Feedback.plist
: The feedback interface.
en.lproj/Root.strings
is generated from the .plist
files by genstrings.py
. A typical .plist
item looks like this:
<dict>
<key>Title</key>
<string>SELECT_SERVER_REGION</string>
<key>TitleDefault</key>
<string>Select server region</string>
<key>TitleDescription</key>
<string>Settings item text. Leads to the user being able to choose which country/region they want to use a Psiphon Server in. Should be kept short.</string>
<key>BundleTable</key>
<string>PsiphonClientCommonLibrary</string>
<key>Key</key>
<string>regionSelection</string>
<key>Type</key>
<string>IASKCustomViewSpecifier</string>
<key>DefaultValue</key>
<string></string>
</dict>
Title
is the string key for the string. It must not be the string itself. (For the minor/major edit reasons described above.)TitleDefault
is the "default" (i.e., English) value for the string, as passed toNSLocalizedStringWithDefaultValue
.TitleDescription
is the description/comment/directive for the translator. It should contain context, instructions, etc.BundleTable
will always bePsiphonClientCommonLibrary
for.plist
files in this project (but not so for the app projects that use this library).
If a string in a .plist
should not be translated, it should look like this:
<dict>
<key>Title</key>
<string>Français</string>
</dict>
In addition to Title
, TitleDefault
, TitleDescription
, there are similar attributes for FooterText
, IASKSubtitle
, and IASKPlaceholder
.
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.
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.
-
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. You can find the correct language mapping for iOS apps by going to Project settings, Info tab, and clicking+
to show the languages and codes (don't actually add the language, though). -
Run
transifex_pull.py
. This will pull all translations, including the newly added one. You should see thatPsiphonClientCommonLibrary/Resources/Strings/<new-language>.lproj/Root.strings
andLocalizable.strings
have been created. -
Add the language to our in-app language selector. In
Example/PsiphonClientCommonLibrary/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.
To get the name of a language in that language, check the Windows code or website code, or look at the Omniglot list.
Run pod update PsiphonClientCommonLibrary
in the Example
directory. Do some testing. Commit.
Psiphon Inc.
PsiphonClientCommonLibrary is available under the GPLv3 license. See the LICENSE file for more info.