Skip to content

Commit 5a01edd

Browse files
authored
Merge pull request #76 from phrase/add-documentation-to-readme
Add documentation to readme
2 parents 1a46041 + 588b55c commit 5a01edd

File tree

1 file changed

+220
-1
lines changed

1 file changed

+220
-1
lines changed

README.md

Lines changed: 220 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,228 @@
22

33
Publish your translations faster and simpler than ever before. Stop waiting for the next deployment and start publishing all your translations in real-time directly in Phrase.
44

5+
For more details on how OTA works head over to the Phrase Help Center: https://support.phrase.com/hc/en-us/articles/5804059067804-Over-the-Air-Strings
6+
57
## Instructions
68

7-
Head over to the Phrase Help Center to learn about this feature and how to use it in your apps: https://support.phrase.com/hc/en-us/articles/5804059067804-Over-the-Air-Strings-
9+
With the SDK, the app regularly checks for updated translations and downloads them in the background. Translations are fetched when `updateTranslations` is called, which should usually happen in `onCreate`.
10+
11+
12+
### Requirements
13+
- The SDK requires at least appcompat version 1.2.0. If using an older version of appcompat, consider using SDK version [2.1.3](https://github.com/phrase/phrase-android/releases/tag/2.1.3)
14+
- The library depends on AndroidX to support backward compatible UI elements such as the toolbar.
15+
16+
### Include the SDK
17+
Add a new repository to the root `build.gradle`:
18+
19+
```
20+
allprojects {
21+
repositories {
22+
...
23+
maven { url "https://maven.download.phrase.com" }
24+
}
25+
}
26+
```
27+
28+
Add the library as a dependency:
29+
30+
```
31+
dependencies {
32+
implementation "com.phrase.android:ota-sdk:3.10.2"
33+
...
34+
}
35+
```
36+
37+
### Jetpack Compose support
38+
To enable Jetpack Compose support for OTA translations, follow these steps:
39+
1. Add the library `implementation "com.phrase.android:ota-sdk-compose:3.10.2"` to the root build.gradle.
40+
2. Wrap the Jetpack Compose code in `Phrase { ... }`.
41+
42+
### Configuration
43+
Initialize the SDK in the application class and add the distribution ID and environment secret. Classes inheriting from Application should overwrite `attachBaseContext` to enable translations outside of the activity context:
44+
45+
```java
46+
public class MainApplication extends Application {
47+
@Override
48+
public void onCreate() {
49+
super.onCreate();
50+
Phrase.setup(this, "DISTRIBUTION_ID", "ENVIRONMENT_TOKEN");
51+
Phrase.updateTranslations();
52+
}
53+
54+
@Override
55+
protected void attachBaseContext(Context newBase) {
56+
super.attachBaseContext(Phrase.wrapApplicationContext(newBase));
57+
}
58+
}
59+
```
60+
61+
Iinject the SDK in each activity, e.g. by creating a base activity which all other activities inherit from:
62+
63+
```java
64+
public class BaseActivity extends AppCompatActivity {
65+
@NonNull
66+
@Override
67+
public AppCompatDelegate getDelegate() {
68+
return Phrase.getDelegate(this, super.getDelegate());
69+
}
70+
}
71+
```
72+
73+
Translations can be used as usual in layouts:
74+
```xml
75+
<TextView android:text="@string/translation_key" />
76+
```
77+
And inside code:
78+
```java
79+
TextView text = (TextView) findViewById(R.id.text_id);
80+
text.setText(R.string.translation_key);
81+
```
82+
83+
Some libraries do not support automatically unwrapping the context and expect a specific class. In this case context wrapping in Jetpack Compose components can be disabled with:
84+
85+
```
86+
Phrase(contextWrapping = false) {
87+
Text( text = phraseString(R.string.test) )
88+
}
89+
```
90+
91+
### Configurations for log levels:
92+
93+
Java
94+
```java
95+
PhraseLog.setLogLevel(Severity.Debug);
96+
```
97+
98+
Kotlin
99+
```kotlin
100+
PhraseLog.logLevel = Severity.Verbose
101+
```
102+
103+
Other supported logging values: `None`, `Error`, `Warning`, `Info`, `Debug`, `Verbose`
104+
105+
### Custom app version
106+
The SDK uses the app version by default to return a release which matches the release constraints for the min and max version. The app version must use semantic versioning otherwise no translation update is returned. In case the app does not use semantic versioning it is possible to manually override the used app version.
107+
108+
Example:
109+
`Phrase.setAppVersion("3.2.4");`
110+
The version must be set before calling `updateTranslations()`.
111+
112+
### Set timeout
113+
The default timeout for translation downloads is set to 10s. The default can be changed with:
114+
```
115+
// Timeout in milliseconds
116+
Phrase.setTimeout(10000);
117+
```
118+
119+
### Update callback
120+
If the handling of successful translation updates is required, attach a callback handler:
121+
122+
```java
123+
Phrase.updateTranslations(new TranslationsSyncCallback() {
124+
@Override
125+
public void onSuccess(boolean translationsChanged) {
126+
}
127+
128+
@Override
129+
public void onFailure() {
130+
}
131+
});
132+
```
133+
134+
Translation updates can also be triggered manually. Newly fetched translations are displayed upon the next application launch.
135+
136+
To make the latest translations immediately available, use the method `Phrase.applyPendingUpdates()`. This can be combined with listening for translation updates:
137+
138+
```java
139+
Phrase.updateTranslations(new TranslationsSyncCallback() {
140+
@Override
141+
public void onSuccess(boolean translationsChanged) {
142+
if(translationsChanged) {
143+
Phrase.applyPendingUpdates()
144+
// Custom logic to refresh UI
145+
}
146+
}
147+
148+
@Override
149+
public void onFailure() {
150+
}
151+
});
152+
```
153+
154+
The UI does not display translations automatically and must be recreated.
155+
156+
### Configure US data center
157+
Phrase US data center is also supported. The US data center can be configured by calling:
158+
159+
```
160+
Phrase.setHost("https://ota.us.phrase.com/")
161+
```
162+
163+
### Fallback
164+
In case it is not possible to reach Phrase due to a missing network connection of the client or a service interruption, the SDK uses the bundled translations from the resource file. The regular updating of the bundled translations in the app is recommended. The SDK also caches translations locally on the device. If such a cache exists, it is used until the next translation update.
165+
166+
The SDK uses the most recent release for the translations. In case the versionName for the app is set, the most recent release that satisfies the version restrictions will be used.
167+
168+
### Add a new language
169+
Creating the new language in Phrase and create a new release. The SDK fetches the language when this is the device language of a user. Regularly adding a new strings.xml for new languages files when releasing a new app version is recommended or users will only see the fallback translations determined by Android at the first start of the app.
170+
171+
### Auditing
172+
The SDK is closed source and can not be viewed or modified. If it is an organization requirement, audits can be provided. Contact us for more details if required.
173+
174+
### Custom View Support
175+
Custom views can be translated using styled attributes. Since TypedArray does not allow overwriting the resources, slight changes in the custom view are required:
176+
177+
### Kotlin example
178+
179+
Before:
180+
181+
```kotlin
182+
context.obtainStyledAttributes(attrs, R.styleable.CustomView, defStyleAttr, 0).use {
183+
text = it.getText(R.styleable.CustomView_android_text)
184+
}
185+
```
186+
After:
187+
188+
```kotlin
189+
context.obtainStyledAttributes(attrs, R.styleable.CustomView, defStyleAttr, 0).use {
190+
text = it.getTextWithPhrase(R.styleable.CustomView_android_text)
191+
}
192+
```
193+
194+
### Java example
195+
196+
Before:
197+
198+
```java
199+
final TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomView, defStyleAttr, 0);
200+
try {
201+
setText(ta.getText(R.styleable.CustomView_android_text));
202+
} finally {
203+
ta.recycle();
204+
}
205+
```
206+
After:
207+
208+
```java
209+
final TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomView, defStyleAttr, 0);
210+
try {
211+
setText(PhraseTypedArray.getTextWithPhrase(ta, R.styleable.CustomView_android_text));
212+
} finally {
213+
ta.recycle();
214+
}
215+
```
216+
217+
Example [app](https://github.com/phrase/android-sdk-example)
218+
219+
### Troubleshooting
220+
**If translations are not being updated**
221+
- Ensure distribution id and environment secret are correct.
222+
- Ensure a release was created on for the current app version.
223+
- Reload the ViewController to make changes appear immediately.
224+
225+
If the wrong version of a translation is being used, ensure a release with the latest translations and the current app version is available and the `versionName` for the app set and are using the `<major>.<minor>.<point>`. format.
226+
8227

9228
## Known limitations
10229

0 commit comments

Comments
 (0)