NSLocalizedString ze zmienną Swift


85

Próbuję zlokalizować moją aplikację przy użyciu NSLocalizedString. Kiedy importuję plik XLIFF, większość działa jak urok, ale coś nie działa, a niektóre ciągi nie są zlokalizowane. Zauważyłem, że problem pochodzi z NSLocalizedString zawierającego coś zmiennego wewnątrz, na przykład:

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

lub

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

Może to nie jest poprawna składnia dla tego rodzaju rzeczy. Ktoś może mi wyjaśnić, jak to zrobić szybko? Dziękuję Ci bardzo.


To jest bardzo dobry artykuł o lokalizacji w Swift dla solidnej architektury
Mendy,

Odpowiedzi:


133

Możesz użyć sprintfparametrów formatu w obrębie NSLocalizedString, więc Twój przykład może wyglądać następująco:

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

6
Jak to wygląda w Localizable.string
Van Du Tran

tak samo jak w Obj-C:" - %d Notifica"=" - %d Notifica";
ReDetection

3
Jak zamienić ciąg? Próbowałem użyć %smodyfikatora, który nie działał = \
igrek

12
@igrek Służy %@do zastępowania łańcucha.
Yeehaw,

2
Odniesienie do tych parametrów formatowania to developer.apple.com/library/content/documentation/Cocoa/…
Shaun Dychko

94

W sesji nr 412 WWDC2014 „Lokalizowanie za pomocą Xcode 6” właściwą drogą do tego w języku Swift jest:

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

Dlaczego musisz używać NSLocalizedString (...)? czy to się nie dzieje w implementacji String.localizedStringWithFormat (...)?
Yitzchak


1
Dzięki, już to widziałem po tym, jak zapytałem. Będzie to bardzo pomocne dla innych, więc dzięki
Yitzchak

25

Postępowałem zgodnie z podejściem tworzenia rozszerzenia do String, ponieważ mam wiele ciągów do zlokalizowania.

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

Aby użyć go do lokalizacji w kodzie, wykonaj:

self.descriptionView.text = "Description".localized

W przypadku ciągów ze zmiennymi dynamicznymi wykonaj:

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

Zadeklaruj ciągi w plikach String dla różnych języków (przykład: arabski i angielski)

wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj

Mam nadzieję, że pomoże!


2
Ale wydaje mi się, że po prostu dołączasz czas do sznurka. Co by było, gdyby twój zlokalizowany ciąg był podobny The doors open at %@ o'clock. Czy Twoje rozwiązanie nadal działałoby?
Houman

Tak, działa idealnie, ponieważ od tyłu mam czas jako String.
JaspreetKour

1
Dziękuję za odniesienie do Localizable.strings. Jednak myślę, że @Houman ma uzasadnione obawy.
Matt,

Nie wiem, dlaczego ludzie chcą porzucić wartość „komentarza”. Daje opis tekstu i jego cel inżynierom lokalizacyjnym, bez których nie mogą rozpoznać zamiaru użycia tego tekstu na przycisku lub jako etykieta itp.
Satyam

7

Wypróbowałem powyższe rozwiązania, ale poniższy kod działał dla mnie

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

Oto rozszerzenie, którego używam w String, dodaje funkcję localizeWithFormat ze zmiennymi argumentami,

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")
     }
}

Stosowanie:

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)

Uważaj tylko, aby nie używać tych samych nazw funkcji i właściwości, które ma String. Zwykle używam 3-literowego przedrostka dla wszystkich moich funkcji frameworka.


-5

Założyłem extensionsię String, ponieważ miałem wiele stringsdo być localized.

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

Na przykład:

let myValue = 10
let anotherValue = "another value"

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

6
Dużą wadą tego podejścia jest to, że musisz ręcznie wyodrębnić ciągi znaków, aby wysłać je do tłumacza, ponieważ Editor > Export for Localization...ich nie odbierze.
Jason Moore

Biorąc pod uwagę to, co zasugerował @JasonMoore, nie sądzę, że jest to właściwe podejście.
Yuchen Zhong

@JasonMoore całkowicie się z tobą zgadzam. Czy któryś z was znalazł na to rozwiązanie?
gasparuff

nie wiem, dlaczego to rozwiązanie jest obniżone :(. i prawie poniższe gniazdo poniżej rozwiązania jest takie samo, ale ma poprawne
Amr Angry
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.