Proceso de localización de aplicaciones IOS en Vivid Money

¡Hola! Si su aplicación admite diferentes idiomas, es probable que haya encontrado problemas relacionados con la localización: errores en las claves de escritura, valores faltantes para los idiomas, la necesidad de reconstruir la aplicación en caso de ediciones de traducción de emergencia. No son los momentos más agradables de desarrollo, ¿verdad?





Este artículo discutirá cómo funciona la localización en Vivid.Money: le diremos qué herramienta de localización eligió, qué problemas encontró y cómo se resolvieron.





Para comprender mejor los detalles del proyecto, puede leer este material y le sugerimos comenzar este artículo sin más preámbulos.





¿Qué método de localización elegiste?

Nuestros requisitos de localización incluyen los siguientes puntos:





  • Sincronización entre plataformas (iOS, Android, Backend) para una única fuente de verdad;





  • Comprobar la ortografía correcta de las claves utilizadas durante la compilación para eliminar la posibilidad de cometer un error tipográfico en el nombre de la clave;





  • No es necesario que los desarrolladores introduzcan localizaciones para diferentes idiomas de forma independiente para que los desarrolladores dediquen más tiempo a hacer lo que deberían: implementar funciones;





  • Facilidad de interacción con traductores;





  • La capacidad de cambiar valores clave sin reconstruir la aplicación.





Apple .strings .stringsdict. .strings (“”: “”), . .stringsdict plural plist. , NSLocalizedString. Apple .





  , : , , , . XLIFF ( , XML), . , - .





, , , . , , , :









Lokalise





Phrase





OneSky





POEditor









+





-





-





-









+





+





-





+





plural





+





+





+/-





+





SDK





+





+





+





-









+





-





-





-





/





+





-





-





-









+





-





-





-









+





+/-





-





-









https://lokalise.com/pricing





https://phrase.com/pricing/





https://www.oneskyapp.com/pricing/





https://poeditor.com/pricing/





Crowdin, . , - , . Lokalise, , . , , .





lokalise , , , . : 





  • ;





  • Fastlane, ;





  • API/CLI;





  • SDK.





Lokalise .





, 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.





, : 





  1. ;





  2. Lokalise , ;





  3. , , , debug , Localisation.swift;





  4. , , , ;





  5. Lokalise;





  6. , , production Lokalise , ;





  7. production Lokalise;





  8. .





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!








All Articles