Processo de localização de aplicativos IOS na Vivid Money

Olá! Se seu aplicativo oferece suporte a idiomas diferentes, provavelmente você encontrou problemas relacionados à localização: erros ao escrever chaves, valores ausentes para idiomas, necessidade de reconstruir o aplicativo em caso de edições de tradução de emergência. Não são os momentos mais agradáveis ​​de desenvolvimento, não é?





Este artigo discutirá como a localização funciona no Vivid.Money: nós lhe diremos qual ferramenta de localização você escolheu, quais problemas você encontrou e como eles foram resolvidos.





Para uma melhor compreensão das especificidades do projeto, você pode ler este material e sugerimos começar este artigo sem mais delongas





Qual método de localização você escolheu

Nossos requisitos de localização incluem os seguintes pontos:





  • Sincronização entre plataformas (iOS, Android, Backend) para uma única fonte de verdade;





  • Verificar a grafia correta das chaves usadas durante a compilação para eliminar a possibilidade de cometer erros de digitação no nome da chave;





  • Não há necessidade de os desenvolvedores introduzirem localizações de forma independente para idiomas diferentes para que os desenvolvedores passem mais tempo fazendo o que deveriam - implementar recursos;





  • Facilidade de interação com tradutores;





  • A capacidade de alterar valores-chave sem reconstruir o aplicativo.





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