1

Is it possible to find all localization tables which are available in a iOS Project?


Background:

In a Swift based iOS project I am using multiple, localized .strings files. For example one file containing common strings used in different project, one file project specific strings, etc.

This works fine using a custom localization method which checks if a given string is found in file/table A and continues its search in file/table B if no translation is found:

func localizedString(forKey key: String) -> String {
    // Search in project specific, default file Localizable.strings
    var result = Bundle.main.localizedString(forKey: key, value: nil, table: nil)

    // If now translation was found, continue search in shared file "Common.strings"
    if result == key {
        result = Bundle.main.localizedString(forKey: key, value: nil, table: "Common")
    }

    if result == key {
        result = Bundle.main.localizedString(forKey: key, value: nil, table: "OtherFile")
    }

    ...

    return result
}

Is it possible to extend this to a more general solution where I do not have to specify the files/tables manually, but where this is done automatically? This would allow to use the same code in different projects with different Strings-Files.

// PSEUDOCODE    
func localizedString(forKey key: String) -> String {
    for tableName in Bundle.main.allLocalizdationTables {   // DOES NOT EXIST...
        var result = Bundle.main.localizedString(forKey: key, value: nil, table: tableName)

        if result != key {
            return result 
        }
    }

    return key
}

So: Is it possible to

Andrei Herford
  • 17,570
  • 19
  • 91
  • 225
  • 1
    `Bundle.main.urls(forResourcesWithExtension: "strings", subdirectory: nil)` might help. Getting all the URLs, then extract the names of the files... – Larme May 27 '21 at 09:31
  • Thanks @Larme I was not aware, that the `.strings` files are actually included in the compiled Bundle but this indeed the case. If you would like to add this as an answer, I could accept it. – Andrei Herford May 27 '21 at 09:36

1 Answers1

4

This should do the trick:

func localizedString(forKey key: String) -> String {
    guard let filesURL = Bundle.main.urls(forResourcesWithExtension: "strings", subdirectory: nil) else { return key }
    let tablesName = filesURL.map { $0.deletingPathExtension().lastPathComponent }
    for aTableName in tablesName {
        var result = Bundle.main.localizedString(forKey: key, value: nil, table: aTableName)
        if result != key {
            return result
        }
    }
    return key
}
Larme
  • 24,190
  • 6
  • 51
  • 81