This library is an iOS SDK to update the app wording dynamically. The new wording is downloaded from a remote source and merged with the old one. The main advantage is to not redeploy the app to update the wording.
- Update the app wording dynamically from a remote source
- Avoid reploying the app
- Localize a key with the updated wording
- Log events when an error occurs (key missing / merge error)
To run the example project, clone the repo, and run pod install
from the Example directory first.
Setup the library with your credentials in the AppDelegate.swift
for example.
Faberbabel.configure(
projectId: "xxx-xxx-xxx",
baseURL: URL(string: "https://xxx.com")!
)
If you are using extensions, you might want to share one wording for all of your targets. For this, add an App Group Identifier
in the capabilities of your targets, then pass the identifier in the configure
method:
Faberbabel.configure(
projectId: "xxx-xxx-xxx",
baseURL: URL(string: "https://xxx.com")!,
appGroupIdentifier: "group.xxx.com"
)
Instead of using the default configure
method you can control all the dependencies:
- how the wording is fetched
- how error events are handled
- where the fetched wording is located
Faberbabel.configure(
fetcher: MyCustomFetcher(),
logger: MyCustomLogger(),
localizableDirectoryUrl: myCustomLocation
)
You can fetch the wording from a custom source. For this, create an object conforming to the LocalizableFetcher
protocol:
class MyCustomFetcher: LocalizableFetcher {
// MARK: - LocalizableFetcher
func fetch(for lang: String,
completion: @escaping (Result<Localizations, Error>) -> Void) {
let result: Localizations = ["key": "value"]
completion(result)
}
}
When errors occur, events are created and sent to an EventLogger
.
By default some loggers already exists:
ConsoleEventLogger
that prints events to the consoleEmptyLogger
that does nothingCompoundEventLogger
that aggregate multiple loggers
You can create your own event logger by conforming to the EventLogger
protocol. For instance:
class RemoteEventLogger: EventLogger {
// MARK: - EventLogger
func log(_ events: [Event]) {
// send events to remote server
}
}
By default the new Localizable.strings
downloaded from the remote source is stored either in the user library directory if no appGroupIdentifier
is passed, or in the location in the file system of the app group's shared directory.
You can create your custom url and have full control of the location of the localizable directory.
To fetch a new wording from the remote source, simply call the updateWording
method like so:
let wordingRequest = UpdateWordingRequest(
language: .languageCode("fr") , // Optional: Default is '.current'
mergingOptions: [] // Optional: Default is []
// If you want the merge to allow big changes in your wording such as a number of attributes mismatch,
// you can for example use the following :
// mergingOptions: [.allowRemoteEmptyString, .allowAttributeNumberMismatch]
)
Faberbabel.updateWording(
request: wordingRequest,
bundle: .main
) { result in
switch result {
case .success:
// Update UI
case let .failure(error):
// Handle error
}
}
To get the localized version of a key, do not use NSLocalizedString
that will only search for translations in the main bundle, but use the fb_translation
method on String
:
"key".fb_translation // returns the localized string in the current language
You can also fetch a translation for a specific language:
"key".fb_translate(to: "fr")
If a value is not found in specified language, the system will fallback to english.
- iOS 10.0+ / tvOS 10.0+
- Swift 5.0
Faberbabel is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'Faberbabel'
- If you need help, use Twitter.
- If you'd like to ask a general question, use Twitter.
- If you'd like to apply for a job, visit https://careers.fabernovel.com/.
- If you found a bug, open an issue.
- If you have a feature request, open an issue.
- If you want to contribute, submit a pull request.
Faberbabel is owned and maintained by Fabernovel. You can follow us on Twitter at @Fabernovel.
Faberbabel is available under the MIT license. See the LICENSE file for more info.