Локализация и CocoaPods

У меня есть проект, который использует CocoaPods. В результате у меня есть рабочая область, которая содержит два проекта: мой и Pods.

Pods содержит код, который я хотел бы локализовать, и я создал .strings файлов в Pod. Однако NSLocalizedString не может загрузить эти строки. Я подозреваю, что это происходит из-за того, что файла .strings нет в основной сборке, а сборки Pod нет, потому что она скомпилирована в статическую библиотеку.

Есть ли лучший способ локализовать код в проекте CocoaPods, чем в моем основном проекте?


person user1071136    schedule 13.10.2012    source источник
comment
Неа; Я просто поместил локализованные строки основного проекта в отдельную группу/каталог.   -  person user1071136    schedule 09.11.2012
comment
Локализация изменена в newles Xcode. [посмотрите там] [1] Я думаю, что это решило вашу проблему.. :-/ [1]: stackoverflow.com/questions/5349066/   -  person Bimawa    schedule 12.02.2013
comment
Не уверен, как это помогает; мой вопрос был опубликован, когда Xcode был около 4.5. Можете ли вы указать на что-то конкретное?   -  person user1071136    schedule 12.02.2013
comment
Если вы укажете, какие ресурсы находятся в вашем подфайле, они будут скопированы в ваш набор приложений. Тем не менее, локализация ВСЕ ЕЩЕ не работает...   -  person horseshoe7    schedule 14.01.2014


Ответы (5)


NSLocalizedString просто вызывает localizedStringForKey:value:table: NSBundle, поэтому я написал категорию NSBundle, чтобы можно было просмотреть несколько пакетов (которые в iOS являются просто папками):

NSString * const kLocalizedStringNotFound = @"kLocalizedStringNotFound";

+ (NSString *)localizedStringForKey:(NSString *)key
                              value:(NSString *)value
                              table:(NSString *)tableName
                       backupBundle:(NSBundle *)bundle
{
    // First try main bundle
    NSString * string = [[NSBundle mainBundle] localizedStringForKey:key
                                                               value:kLocalizedStringNotFound
                                                               table:tableName];

    // Then try the backup bundle
    if ([string isEqualToString:kLocalizedStringNotFound])
    {
        string = [bundle localizedStringForKey:key
                                         value:kLocalizedStringNotFound
                                         table:tableName];
    }

    // Still not found?
    if ([string isEqualToString:kLocalizedStringNotFound])
    {
        NSLog(@"No localized string for '%@' in '%@'", key, tableName);
        string = value.length > 0 ? value : key;
    }

    return string;
}

Затем переопределил макрос NSLocalizedString в моем префиксном файле:

#undef  NSLocalizedString
#define NSLocalizedString(key, comment) \
[NSBundle localizedStringForKey:key value:nil table:@"MyStringsFile" backupBundle:AlternativeBundleInsideMain]

То же самое для других макросов, если необходимо (например, NSLocalizedStringWithDefaultValue)

person Rivera    schedule 25.04.2013

@Rivera Swift 2.0 версия:

static let kLocalizedStringNotFound = "kLocalizedStringNotFound"

static func localizedStringForKey(key:String,
                                  value:String?,
                                  table:String?,
                                  bundle:NSBundle?) -> String {
    // First try main bundle
    var string:String = NSBundle.mainBundle().localizedStringForKey(key, value: kLocalizedStringNotFound, table: table)

    // Then try the backup bundle
    if string == kLocalizedStringNotFound {
        string = bundle!.localizedStringForKey(key, value: kLocalizedStringNotFound, table: table)
    }

    // Still not found?
    if string == kLocalizedStringNotFound {
        print("No localized string for '\(key)' in '\(table)'")
        if let value = value {
            string = value.characters.count > 0 ? value : key
        } else {
            string = key
        }
    }

    return string;
}
person SwiftArchitect    schedule 29.07.2015

  1. Вы не должны помещать какой-либо файл в проект Pods, потому что команда pod будет пересоздавать проект снова и снова.

    Поэтому поместите строковые файлы в свой собственный проект.

  2. Если вы хотите отправить локализованные строковые файлы в свой собственный модуль, вы должны включить его в пакет и убедиться, что пакет будет установлен в вашем файле Podspec.

Например:

def s.post_install(target)
    puts "\nGenerating YOURPOD resources bundle\n".yellow if config.verbose?
    Dir.chdir File.join(config.project_pods_root, 'YOURPOD') do
        command = "xcodebuild -project YOURPOD.xcodeproj -target YOURPODResources CONFIGURATION_BUILD_DIR=../Resources"
        command << " 2>&1 > /dev/null" unless config.verbose?
        unless system(command)
            raise ::Pod::Informative, "Failed to generate YOURPOD resources bundle"
        end

        File.open(File.join(config.project_pods_root, target.target_definition.copy_resources_script_name), 'a') do |file|
            file.puts "install_resource 'Resources/YOURPODResources.bundle'"
        end
    end
end
person Max Horvath    schedule 27.02.2013
comment
Итак, проблема в том, что строки, находящиеся в проекте Pods, не загружаются с помощью NSLocalizedString. Даже если Pod поставляется с файлами локализации, я не могу использовать их без копирования в свой проект. - person user1071136; 28.02.2013
comment
На самом деле, я слишком быстро прочитал ваш ответ - возможно, вы на правильном пути. Я не могу проверить ответ в данный момент, поэтому вместо этого я буду полагаться на голоса. - person user1071136; 04.03.2013
comment
Любой успех по вышеуказанной проблеме? Мне нужно добавить поддержку нового языка в существующий SDK - person Abhi; 06.03.2017

Лучший подход к локализации ресурсов в модуле (общедоступном или частном — безразлично) — добавить .strings файлы локализации в пакет модуля.

Основное приложение очень разборчиво, когда дело доходит до загрузки файлов локализации из фреймворков pod, вот шаги, которые вы должны выполнить:

1. Создайте файл Localizable.strings и все остальные *.strings файлы, необходимые для локализации, и поместите их в папку примерно так:

структура папок строк

Некоторые ограничения для соблюдения:

  • Имя папки должно быть XX.lproj, где XX — ваше ТОЧНОЕ название языка, примечание: en != en-GB != en-US
  • Все папки lproj должны быть на одном уровне
  • В каждой папке lproj должно быть одинаковое количество файлов .strings и с одинаковыми именами.

2. Настройте файл .podspec, чтобы модуль мог правильно подобрать локализацию и скопировать их в файл .framework.

Пример:

  s.resource = 'your_path/Localizations/**/*', '... possibly other resources'

после выполнения pod install результат в вашей папке Development Pods должен быть примерно таким:

введите здесь описание изображения

Важно проверить, что созданная структура состоит в том, что вся папка .lproj должна находиться в корневой папке, в противном случае основное приложение не сможет правильно подобрать ее.

3. В коде вашего модуля вместо обычного NSLocalizedString вы должны использовать NSLocalizedStringFromTableInBundle:

NSLocalizedStringFromTableInBundle(@"My string", nil, [NSBundle bundleForClass:[MCLoginContext class]], @"String context")

Весь процесс очень деликатный и раздражающий, но это все.

person Kappe    schedule 24.07.2020

для быстрого вы можете использовать перечисление Loc:

enum Loc : String{
case ok = "OK"
case cancel = "Cancel"

var localized: String {
    let s = self.rawValue
    let bundle = Bundle(for: <classname inside the bundle>.self)
    let result = NSLocalizedString(s, tableName: nil, bundle: bundle, value: "", comment: "")
    return result;
}

}

И используйте его так:

let s = Loc.ok.localized
print(s)
person user11630362    schedule 09.09.2020