NSLocalizedString із швидкою змінною


85

Я намагаюся локалізувати свій додаток за допомогою NSLocalizedString. Коли я імпортую файл XLIFF, більшість з них працює як шарм, але щось не відбувається, а деякі рядки не локалізовані. Я помітив, що проблема в NSLocalizedString, що містить щось змінне всередині, наприклад:

NSLocalizedString(" - \(count) Notifica", comment: "sottotitolo prescrizione per le notifiche al singolare")

або

NSLocalizedString("Notifica per \(medicina!) della prescrizione \(prescription!)\nMemo: \(memoTextView.text)", comment: "Messaggio della Local Notification")

Можливо, це не правильний синтаксис для такого роду речей. Хтось може пояснити мені, як це зробити швидко? Дуже дякую.


Це дуже хороша стаття про локалізацію в Swift для надійної архітектури
Менді,

Відповіді:


133

Ви можете використовувати sprintfпараметри формату всередині NSLocalizedString, тому ваш приклад може виглядати так:

let myString = String(format: NSLocalizedString(" - %d Notifica", comment: "sottotitolo prescrizione per le notifiche al singolare"), count)

6
Як це виглядає в Localizable.string
Van Du Tran

те саме, що в Obj-C:" - %d Notifica"=" - %d Notifica";
Перевизначення

3
Як замінити рядок? Я намагався використовувати %sмодифікатор, який не працював = \
igrek

12
@igrek Використовується %@для заміни рядка.
Yeehaw

2
Посиланням на ці параметри форматування є developer.apple.com/library/content/documentation/Cocoa/…
Шон Дичко,

94

На сесії № 412 WWDC2014 "Локалізація за допомогою Xcode 6" правильним шляхом до цього в Swift є такий:

String.localizedStringWithFormat(
    NSLocalizedString(" - %d Notifica",
    comment: "sottotitolo prescrizione per le notifiche al singolare"),
    count)

Навіщо потрібно використовувати NSLocalizedString (...)? хіба це не відбувається у реалізації String.localizedStringWithFormat (...)?
Іцхак,


1
Дякую, я вже бачив це після того, як запитав. Це буде дуже корисно для інших, тому дякую
Іцчак

25

Я дотримувався підходу створення розширення до рядка, оскільки у мене є багато рядків для локалізації.

extension String {
    var localized: String {
        return NSLocalizedString(self, comment:"")
    }
}

Щоб використовувати його для локалізації в коді:

self.descriptionView.text = "Description".localized

Для рядків з динамічними змінними дотримуйтесь:

self.entryTimeLabel.text = "\("Doors-open-at".localized) \(event.eventStartTime)"

Оголосіть рядки у файлах рядків для різних мов (приклад: арабська та англійська)

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

Надія допоможе!


2
Але мені здається, ви просто прикріплюєте час до струни. Що, якби ваш локалізований рядок був таким The doors open at %@ o'clock. Ваше рішення все одно спрацює?
Хоуман,

Так, це працює чудово, оскільки я отримую час як String зі спини.
JaspreetKour

1
Дякуємо за включення посилання на Localizable.strings. Однак я думаю, що @Houman має поважне занепокоєння.
Метт

Я не знаю, чому люди хочуть кинути значення "коментар". Він дає опис тексту та його призначення інженерам з локалізації, без яких вони не можуть зрозуміти наміру використовувати цей текст на кнопці або як ярлик тощо
Satyam

7

Я спробував наведені вище рішення, однак код нижче працював для мене

SWIFT 4

extension String {

    /// Fetches a localized String
    ///
    /// - Returns: return value(String) for key
    public func localized() -> String {
        let path = Bundle.main.path(forResource: "en", ofType: "lproj")
        let bundle = Bundle(path: path!)
        return (bundle?.localizedString(forKey: self, value: nil, table: nil))!
    }


    /// Fetches a localised String Arguments
    ///
    /// - Parameter arguments: parameters to be added in a string
    /// - Returns: localized string
    public func localized(with arguments: [CVarArg]) -> String {
        return String(format: self.localized(), locale: nil, arguments: arguments)
    }

}

// variable in a class
 let tcAndPPMessage = "By_signing_up_or_logging_in,_you_agree_to_our"
                                     .localized(with: [tAndc, pp, signin])

// Localization File String
"By_signing_up_or_logging_in,_you_agree_to_our" = "By signing up or logging in, you agree to our \"%@\" and \"%@\" \nAlready have an Account? \"%@\"";

6

Ось розширення, яке я використовую в рядку, воно додає функцію localizeWithFormat із змінними аргументами,

extension String:{

     func localizeWithFormat(arguments: CVarArg...) -> String{
        return String(format: self.localized, arguments: arguments)        
     }

     var localized: String{
         return Bundle.main.localizedString(forKey: self, value: nil, table: "StandardLocalizations")
     }
}

Використання:

let siriCalendarText = "AnyCalendar"
let localizedText = "LTo use Siri with my app, please set %@ as the default list on your device reminders settings".localizeWithFormat(arguments: siriCalendarTitle)

Тільки будьте обережні, щоб не використовувати ті самі назви функцій та властивостей, що і у String. Зазвичай я використовую префікс із 3 літер для всіх своїх функцій фреймворку.


-5

Я створив extensionдо, Stringоскільки мені довелося stringsбути багатьма localized.

extension String {
    var localized: String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
    }
}

Наприклад:

let myValue = 10
let anotherValue = "another value"

let localizedStr = "This string is localized: \(myValue) \(anotherValue)".localized
print(localizedStr)

6
Основним недоліком цього підходу є те, що вам доведеться вручну витягувати рядки, щоб відправити перекладачу, оскільки Editor > Export for Localization...вони не будуть їх забирати.
Джейсон Мур,

Враховуючи те, що запропонував @JasonMoore, я не вважаю, що це правильний підхід.
Yuchen Zhong

@JasonMoore повністю з вами згоден. Хтось із вас, хлопці, знайшов для цього рішення?
gasparuff

я не знав, чому це рішення є нижчим :(. і майже нижнє гніздо нижче рішення таке саме, але воно має підвищення
Amr Angry
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.