Bonjour! Si votre application prend en charge différentes langues, alors vous avez probablement rencontré des problèmes liés à la localisation: erreurs d'écriture des clés, valeurs manquantes pour les langues, nécessité de reconstruire l'application en cas de modifications de traduction d'urgence. Pas les moments de développement les plus agréables, n'est-ce pas?
Cet article explique comment fonctionne la localisation dans Vivid.Money: nous vous indiquerons quel outil de localisation vous avez choisi, quels problèmes vous avez rencontrés et comment ils ont été résolus.
Pour une meilleure compréhension des spécificités du projet, vous pouvez lire ce matériel, et nous vous suggérons de commencer cet article sans plus tarder
Quelle méthode de localisation avez-vous choisie
Nos exigences de localisation comprennent les points suivants:
Synchronisation entre plateformes (iOS, Android, Backend) pour une seule source de vérité;
Vérifier l'orthographe correcte des clés utilisées lors de la compilation pour éliminer la possibilité de faire une faute de frappe dans le nom de la clé;
Pas besoin pour les développeurs d'introduire indépendamment des localisations pour différentes langues afin que les développeurs passent plus de temps à faire ce qu'ils devraient - mettre en œuvre des fonctionnalités;
Facilité d'interaction avec les traducteurs;
La possibilité de modifier les valeurs de clé sans reconstruire l'application.
Apple .strings .stringsdict. .strings (“”: “”), . .stringsdict plural plist. , NSLocalizedString. Apple .
, : , , , . XLIFF ( , XML), . , - .
, , , . , , , :
|
|
Lokalise |
Phrase |
OneSky |
POEditor |
|
+ |
- |
- |
- |
|
+ |
+ |
- |
+ |
plural |
+ |
+ |
+/- |
+ |
SDK |
+ |
+ |
+ |
- |
|
+ |
- |
- |
- |
/ |
+ |
- |
- |
- |
|
+ |
- |
- |
- |
|
+ |
+/- |
- |
- |
|
|
|
|
https://www.oneskyapp.com/pricing/ |
|
Crowdin, . , - , . Lokalise, , . , , .
lokalise , , , . :
;
Fastlane, ;
API/CLI;
SDK.
, SDK. : , , SDK. , , .
API, Lokalise , . .
, Lokalise SDK, . : . , Lokalise SDK , , , .
(debug/release), .
.strings .stringsdict plutil (property list utility), : .. Ruby:
def self.valid_bundle?(path)
puts 'Validating localization bundle...'
strings = Dir["#{path}/Contents/Resources/*.lproj/*.strings"]
stringsdict = Dir["#{path}/Contents/Resources/*.lproj/*.stringsdict"]
is_valid = true
(strings + stringsdict).each do |path|
stdout, stderr, status = Open3.capture3("plutil -lint #{path}")
unless status.exitstatus == 0
is_valid = false
line = stderr.strip[/on line ([0-9]*)/, 1]
puts "***********************************************".red
puts "Found the invalid string in file at path: #{path}".red
puts "The invalid string: #{File.readlines(path)[line.to_i-1].strip}".red
end
end
puts "***********************************************".red unless is_valid
is_valid
end
Localisation, .
, - . LocalizationFetcher : . , , - . , , Documents, .
, , , Localise.bundle. : Documents .lproj Localizable.strings Localizable.stringsdict Localizable.nocache.strings Localizable.nocache.stringsdict, . “Localizable.nocache” tableName localizedString(forKey:value:table:) , .
, : , , , .
R.swift , .., -, , ( ), -, . .
: Localisation.swift , Localizable.strings Localizable.stringsdict .
?
:
public static let localization_var = "localization_key".localized
public static func localization_method(_ value1: String) -> String {
"localization_method_key".localized(with: value1)
}
localized :
var localized: String {
let localLocalisation = Self.localLocaliseBundle?.localizedString(
forKey: self,
value: nil,
table: nil
)
let serverLocalisation = Self.makeServerLocaliseBundle()?.localizedString(
forKey: self,
value: localLocalisation,
table: “Localizable.nocache”
)
return serverLocalisation ?? localLocalisation ?? self
}
;
, Documents, ;
, , , .
, (localized(with:)), :
func localized(with parameters: CVarArg...) -> String {
let correctLocalizedString: String = {
if localized.starts(with: "%#@") {
return localized
}
return localized
.replacingOccurrences(of: "%s", with: "%@")
.replacingOccurrences(
of: "(%[0-9])\\$s",
with: "$1@",
options: .regularExpression
)
}()
guard !correctLocalizedString.isEmpty else {
return self
}
return String(format: correctLocalizedString, arguments: parameters)
}
:
plural ;
, Lokalise, ;
, ;
, , .
: -, Localizable.stringsdict , ; -, , , plural . , localizedString(forKey:value:table:) plural , Localizable.stringsdict, __NSLocalizedString. plural . , .regularExpression replacingOccurencies(of:with:options:) String , , __NSLocalizedString.
, :
;
Lokalise , ;
, , , debug , Localisation.swift;
, , , ;
Lokalise;
, , production Lokalise , ;
production Lokalise;
.
production Lokalise Gitlab , , , , , .
, .
iOS Android
, , , iOS Android -. , iOS %@, Android %s. , , Android first Lokalise, iOS .
, - . , . . , .
, , .
, 2 “” - debug production. debug , , production - , debug production.
, , production . , - . : , Localisation.swift, . , , .
, Lokalise, - . , .
, , , debug production , . , , , .
, , - , . That’s all, Folks!