Di iPhone NSLocalizedString
mengembalikan string dalam bahasa iPhone. Apakah mungkin untuk memaksa NSLocalizedString
menggunakan bahasa tertentu agar aplikasi dalam bahasa yang berbeda dari perangkat?
Di iPhone NSLocalizedString
mengembalikan string dalam bahasa iPhone. Apakah mungkin untuk memaksa NSLocalizedString
menggunakan bahasa tertentu agar aplikasi dalam bahasa yang berbeda dari perangkat?
Jawaban:
NSLocalizedString()
(dan variasinya) mengakses kunci "AppleLanguages" NSUserDefaults
untuk menentukan pengaturan pengguna untuk bahasa yang diinginkan. Ini mengembalikan array kode bahasa, dengan yang pertama ditetapkan oleh pengguna untuk telepon mereka, dan yang berikutnya digunakan sebagai cadangan jika sumber daya tidak tersedia dalam bahasa yang disukai. (pada desktop, pengguna dapat menentukan beberapa bahasa dengan pemesanan khusus di System Preferences)
Anda dapat mengganti pengaturan global untuk aplikasi Anda sendiri jika ingin menggunakan metode setObject: forKey: untuk mengatur daftar bahasa Anda sendiri. Ini akan diutamakan daripada nilai yang ditetapkan secara global dan dikembalikan ke kode apa pun dalam aplikasi Anda yang melakukan pelokalan. Kode untuk ini akan terlihat seperti:
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"de", @"en", @"fr", nil] forKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize]; //to make the change immediate
Ini akan menjadikan Jerman bahasa pilihan untuk aplikasi Anda, dengan bahasa Inggris dan Prancis sebagai mundur. Anda ingin memanggil ini di awal startup aplikasi Anda. Anda dapat membaca lebih lanjut tentang preferensi bahasa / lokal di sini: Topik Pemrograman Internasionalisasi: Mendapatkan Bahasa dan Lokal Saat Ini
Saya memiliki masalah yang sama baru-baru ini dan saya tidak ingin memulai dan menambal seluruh NSLocalizedString atau memaksa aplikasi untuk memulai kembali agar bahasa baru berfungsi. Saya ingin semuanya berjalan apa adanya.
Solusi saya adalah mengubah kelas bundel utama secara dinamis dan memuat bundel yang sesuai di sana:
File tajuk
@interface NSBundle (Language)
+(void)setLanguage:(NSString*)language;
@end
Penerapan
#import <objc/runtime.h>
static const char _bundle=0;
@interface BundleEx : NSBundle
@end
@implementation BundleEx
-(NSString*)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
{
NSBundle* bundle=objc_getAssociatedObject(self, &_bundle);
return bundle ? [bundle localizedStringForKey:key value:value table:tableName] : [super localizedStringForKey:key value:value table:tableName];
}
@end
@implementation NSBundle (Language)
+(void)setLanguage:(NSString*)language
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
object_setClass([NSBundle mainBundle],[BundleEx class]);
});
objc_setAssociatedObject([NSBundle mainBundle], &_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
Jadi pada dasarnya, ketika aplikasi Anda mulai dan sebelum Anda memuat controller pertama Anda, cukup hubungi:
[NSBundle setLanguage:@"en"];
Ketika pengguna Anda mengubah bahasa pilihannya di layar pengaturan Anda, cukup panggil lagi:
[NSBundle setLanguage:@"fr"];
Untuk mengatur ulang ke default sistem, cukup lewati nol:
[NSBundle setLanguage:nil];
Nikmati...
Bagi mereka yang membutuhkan versi Swift:
var bundleKey: UInt8 = 0
class AnyLanguageBundle: Bundle {
override func localizedString(forKey key: String,
value: String?,
table tableName: String?) -> String {
guard let path = objc_getAssociatedObject(self, &bundleKey) as? String,
let bundle = Bundle(path: path) else {
return super.localizedString(forKey: key, value: value, table: tableName)
}
return bundle.localizedString(forKey: key, value: value, table: tableName)
}
}
extension Bundle {
class func setLanguage(_ language: String) {
defer {
object_setClass(Bundle.main, AnyLanguageBundle.self)
}
objc_setAssociatedObject(Bundle.main, &bundleKey, Bundle.main.path(forResource: language, ofType: "lproj"), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
Saya biasanya melakukan ini dengan cara ini, tetapi Anda HARUS memiliki semua file pelokalan dalam proyek Anda.
@implementation Language
static NSBundle *bundle = nil;
+(void)initialize
{
NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:@"AppleLanguages"];
NSString *current = [[languages objectAtIndex:0] retain];
[self setLanguage:current];
}
/*
example calls:
[Language setLanguage:@"it"];
[Language setLanguage:@"de"];
*/
+(void)setLanguage:(NSString *)l
{
NSLog(@"preferredLang: %@", l);
NSString *path = [[ NSBundle mainBundle ] pathForResource:l ofType:@"lproj" ];
bundle = [[NSBundle bundleWithPath:path] retain];
}
+(NSString *)get:(NSString *)key alter:(NSString *)alternate
{
return [bundle localizedStringForKey:key value:alternate table:nil];
}
@end
Jangan gunakan di iOS 9. Ini mengembalikan nol untuk semua string melewatinya.
Saya telah menemukan solusi lain yang memungkinkan Anda untuk memperbarui string bahasa, tanpa memulai ulang aplikasi dan kompatibel dengan genstrings:
Letakkan makro ini di Prefix.pch:
#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]
dan di mana pun Anda membutuhkan penggunaan string lokal:
NSLocalizedStringFromTableInBundle(@"GalleryTitleKey", nil, currentLanguageBundle, @"")
Untuk mengatur penggunaan bahasa:
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];
Bekerja bahkan dengan hopping bahasa berurutan seperti:
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"fr"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"it"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
Seperti yang dikatakan sebelumnya, lakukan saja:
[[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:@"el", nil] forKey:@"AppleLanguages"];
Tetapi untuk menghindari keharusan me-restart aplikasi, letakkan baris pada metode utama main.m
, sesaat sebelum UIApplicationMain
(...).
NSAutoreleasePool * pool ..
atau beberapa objek autoreleased akan bocor.
[[NSBundle mainBundle] URLForResource:withExtension:]
sebelumnya.
Trik untuk menggunakan bahasa tertentu dengan memilihnya dari aplikasi adalah memaksa NSLocalizedString
untuk menggunakan bundel tertentu tergantung pada bahasa yang dipilih,
di sini adalah posting yang telah saya tulis untuk lokalisasi muka pembelajaran ini di aplikasi ios
dan di sini adalah kode satu contoh lokalisasi muka aplikasi di aplikasi ios
Apa pendapat Anda tentang solusi ini untuk Swift 3?
extension String {
func localized(forLanguage language: String = Locale.preferredLanguages.first!.components(separatedBy: "-").first!) -> String {
guard let path = Bundle.main.path(forResource: language == "en" ? "Base" : language, ofType: "lproj") else {
let basePath = Bundle.main.path(forResource: "Base", ofType: "lproj")!
return Bundle(path: basePath)!.localizedString(forKey: self, value: "", table: nil)
}
return Bundle(path: path)!.localizedString(forKey: self, value: "", table: nil)
}
}
Penggunaan sederhana:
"report".localized(forLanguage: "pl") //forced language
"report".localized() //default language selected by user in settings, in case when your app doesnt support selected lanaguage, the default one is selected, here is an english.
Seperti yang disebutkan Brian Webster, bahasa perlu diatur "kapan saja lebih awal dalam startup aplikasi Anda". Saya pikir applicationDidFinishLaunching:
dari AppDelegate
seharusnya menjadi tempat yang cocok untuk melakukannya, karena itu di mana aku melakukan semua inisialisasi lainnya.
Tetapi seperti yang disebutkan oleh William Denniss, itu tampaknya memiliki efek hanya setelah aplikasi di-restart, yang agak tidak berguna.
Tampaknya berfungsi dengan baik jika saya meletakkan kode di fungsi utama, meskipun:
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// Force language to Swedish.
[[NSUserDefaults standardUserDefaults]
setObject:[NSArray arrayWithObject:@"sv"]
forKey:@"AppleLanguages"];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
Saya menghargai komentar ini.
[[NSUserDefaults standardUserDefaults] synchronize];
setelah meneleponsetObject:forKey:
Saya suka metode terbaik Mauro Delrio. Saya juga telah menambahkan yang berikut ini di Project_Prefix.pch saya
#import "Language.h"
#define MyLocalizedString(key, alt) [Language get:key alter:alt]
Jadi jika Anda ingin menggunakan metode standar (yang menggunakan NSLocalizedString), Anda dapat membuat substitusi sintaksis cepat di semua file.
NSLocalizedString()
membaca nilai untuk kunci AppleLanguages
dari standar pengguna standar ( [NSUserDefaults standardUserDefaults]
). Ini menggunakan nilai itu untuk memilih lokalisasi yang tepat di antara semua lokalisasi yang ada saat runtime. Ketika Apple membuat kamus default pengguna saat peluncuran aplikasi, mereka mencari kunci bahasa yang disukai dalam preferensi sistem dan menyalin nilainya dari sana. Ini juga menjelaskan misalnya mengapa mengubah pengaturan bahasa di OS X tidak berpengaruh pada menjalankan aplikasi, hanya pada aplikasi yang dimulai setelahnya. Setelah disalin, nilainya tidak diperbarui hanya karena pengaturannya berubah. Itu sebabnya iOS memulai ulang semua aplikasi jika Anda mengubah bahasa.
Namun, semua nilai kamus default pengguna dapat ditimpa oleh argumen baris perintah. Lihat NSUserDefaults
dokumentasi di NSArgumentDomain
. Ini bahkan termasuk nilai-nilai yang diambil dari file preferensi aplikasi (.plist). Ini sangat bagus untuk diketahui jika Anda ingin mengubah nilai hanya sekali untuk pengujian .
Jadi jika Anda ingin mengubah bahasa hanya untuk pengujian, Anda mungkin tidak ingin mengubah kode Anda (jika Anda lupa untuk menghapus kode ini nanti ...), alih-alih minta Xcode untuk memulai aplikasi Anda dengan parameter baris perintah ( mis. gunakan lokalisasi bahasa Spanyol):
Tidak perlu menyentuh kode Anda sama sekali. Cukup buat skema yang berbeda untuk bahasa yang berbeda dan Anda dapat dengan cepat memulai aplikasi sekali dalam satu bahasa dan sekali dalam yang lain hanya dengan mengganti skema.
Options
seperti halnya dengan versi Xcode yang lebih baru yang ditawarkan Apple yang demikian juga.
Saya datang dengan solusi yang memungkinkan Anda untuk menggunakannya NSLocalizedString
. Saya membuat kategori NSBundle
panggilan NSBundle+RunTimeLanguage
. Antarmuka seperti ini.
// NSBundle+RunTimeLanguage.h
#import <Foundation/Foundation.h>
@interface NSBundle (RunTimeLanguage)
#define NSLocalizedString(key, comment) [[NSBundle mainBundle] runTimeLocalizedStringForKey:(key) value:@"" table:nil]
- (NSString *)runTimeLocalizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName;
@end
Implementasinya seperti ini.
// NSBundle+RunTimeLanguage.m
#import "NSBundle+RunTimeLanguage.h"
#import "AppDelegate.h"
@implementation NSBundle (RunTimeLanguage)
- (NSString *)runTimeLocalizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
{
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSString *path= [[NSBundle mainBundle] pathForResource:[appDelegate languageCode] ofType:@"lproj"];
NSBundle *languageBundle = [NSBundle bundleWithPath:path];
NSString *localizedString=[languageBundle localizedStringForKey:key value:key table:nil];
return localizedString;
}
@end
Daripada hanya menambahkan impor NSBundle+RunTimeLanguage.h
ke file yang digunakan NSLocalizedString
.
Seperti yang Anda lihat, saya menyimpan kode bahasa saya di properti AppDelegate
. Ini dapat disimpan di mana saja yang Anda inginkan.
Satu-satunya hal yang saya tidak suka tentang ini adalah Peringatan yang NSLocalizedString
didefinisikan ulang marco. Mungkin seseorang dapat membantu saya memperbaiki bagian ini.
#undef NSLocalizedString
sesaat sebelum #define
menonaktifkan peringatan
Ini hal pertama yang harus Anda lakukan adalah melokalkan aplikasi Anda dengan setidaknya dua bahasa (Inggris dan Perancis dalam contoh ini).
Dalam kode Anda, alih-alih menggunakan NSLocalizedString(key, comment)
, gunakan makro yang MYLocalizedString(key, comment)
ditentukan seperti ini:
#define MYLocalizedString(key, comment) [[MYLocalizationSystem sharedInstance] localizedStringForKey:(key) value:(comment)];
MYLocalizationSystem
Singleton ini akan:
Saat pengguna mengubah bahasa aplikasi dalam bahasa Prancis, hubungi [[MYLocalizationSystem sharedInstance] setLanguage:@"fr"];
- (void)setLanguage:(NSString *)lang
{
NSString *path = [[NSBundle mainBundle] pathForResource:lang ofType:@"lproj"];
if (!path)
{
_bundle = [NSBundle mainBundle];
NSLog(@"Warning: No lproj for %@, system default set instead !", lang);
return;
}
_bundle = [NSBundle bundleWithPath:path];
}
Dalam contoh ini metode ini mengatur bundel lokal ke fr.lproj
Setelah Anda menyetel bundel yang dilokalkan, Anda akan bisa mendapatkan string yang dilokalisasikan darinya dengan metode ini:
- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value
{
// bundle was initialized with [NSBundle mainBundle] as default and modified in setLanguage method
return [self.bundle localizedStringForKey:key value:value table:nil];
}
Semoga ini bisa membantu Anda.
Anda akan menemukan rincian lebih lanjut dalam artikel ini dari NSWinery.io
Ekstensi Swift 3:
extension Locale {
static var preferredLanguage: String {
get {
return self.preferredLanguages.first ?? "en"
}
set {
UserDefaults.standard.set([newValue], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()
}
}
}
extension String {
var localized: String {
var result: String
let languageCode = Locale.preferredLanguage //en-US
var path = Bundle.main.path(forResource: languageCode, ofType: "lproj")
if path == nil, let hyphenRange = languageCode.range(of: "-") {
let languageCodeShort = languageCode.substring(to: hyphenRange.lowerBound) // en
path = Bundle.main.path(forResource: languageCodeShort, ofType: "lproj")
}
if let path = path, let locBundle = Bundle(path: path) {
result = locBundle.localizedString(forKey: self, value: nil, table: nil)
} else {
result = NSLocalizedString(self, comment: "")
}
return result
}
}
Pemakaian:
Locale.preferredLanguage = "uk"
label.text = "localizedKey".localized
Dalam file .pch untuk mendefinisikan:
#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]
#define NSLocalizedString(str,nil) NSLocalizedStringFromTableInBundle(str, nil, currentLanguageBundle, @"")
Mungkin Anda harus melengkapi ini (pada file .pch setelah #import):
extern NSBundle* bundle; // Declared on Language.m
#ifdef NSLocalizedString
#undef NSLocalizedString
// Delete this line to avoid warning
#warning "Undefining NSLocalizedString"
#endif
#define NSLocalizedString(key, comment) \
[bundle localizedStringForKey:(key) value:@"" table:nil]
Solusi Swift 3:
let languages = ["bs", "zh-Hant", "en", "fi", "ko", "lv", "ms", "pl", "pt-BR", "ru", "sr-Latn", "sk", "es", "tr"]
UserDefaults.standard.set([languages[0]], forKey: "AppleLanguages")
Memberi beberapa contoh kode bahasa yang dapat digunakan. Semoga ini membantu
Anda bisa membangun sub-bundel dengan set string terlokalisasi yang ingin Anda lakukan dengan ini, dan kemudian gunakan NSLocalizedStringFromTableInBundle()
untuk memuatnya. (Saya berasumsi bahwa ini adalah konten yang terpisah dari lokalisasi UI normal yang mungkin Anda lakukan di aplikasi.)
untuk kasus saya, saya punya dua file terlokalisasi, ja dan en
dan saya ingin memaksanya untuk en jika bahasa pilihan dalam sistem tidak en atau ja
saya akan mengedit file main.m
Saya akan memeriksa apakah pilihan pertama adalah en atau ja, jika tidak maka saya akan mengubah bahasa pilihan kedua menjadi en.
int main(int argc, char *argv[])
{
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSString *lang = [[NSLocale preferredLanguages] objectAtIndex:0];
if (![lang isEqualToString:@"en"] && ![lang isEqualToString:@"ja"]){
NSMutableArray *array = [[NSMutableArray alloc] initWithArray:[NSLocale preferredLanguages]];
[array replaceObjectAtIndex:1 withObject:@"en"];
[[NSUserDefaults standardUserDefaults] setObject:array forKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
Anda dapat melakukan sesuatu seperti ini:
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Localizable" ofType:@"strings" inDirectory:nil forLocalization:@"es"];
NSBundle *spanishBundle = [[NSBundle alloc] initWithPath:[bundlePath stringByDeletingLastPathComponent]];
NSLocalizedStringFromTableInBundle(@"House", nil, spanishBundle, nil):
Berdasarkan jawaban Tudorizer untuk mengubah bahasa tanpa meninggalkan atau memulai ulang aplikasi.
Alih-alih makro, gunakan kelas untuk mengakses bahasa pilihan untuk memeriksa apakah ada kode bahasa tertentu.
Di bawah ini adalah kelas yang digunakan untuk mendapatkan bundel bahasa saat ini yang berfungsi untuk iOS 9:
@implementation OSLocalization
+ (NSBundle *)currentLanguageBundle
{
// Default language incase an unsupported language is found
NSString *language = @"en";
if ([NSLocale preferredLanguages].count) {
// Check first object to be of type "en","es" etc
// Codes seen by my eyes: "en-US","en","es-US","es" etc
NSString *letterCode = [[NSLocale preferredLanguages] objectAtIndex:0];
if ([letterCode rangeOfString:@"en"].location != NSNotFound) {
// English
language = @"en";
} else if ([letterCode rangeOfString:@"es"].location != NSNotFound) {
// Spanish
language = @"es";
} else if ([letterCode rangeOfString:@"fr"].location != NSNotFound) {
// French
language = @"fr";
} // Add more if needed
}
return [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]];
}
/// Check if preferred language is English
+ (BOOL)isCurrentLanguageEnglish
{
if (![NSLocale preferredLanguages].count) {
// Just incase check for no items in array
return YES;
}
if ([[[NSLocale preferredLanguages] objectAtIndex:0] rangeOfString:@"en"].location == NSNotFound) {
// No letter code for english found
return NO;
} else {
// Tis English
return YES;
}
}
/* Swap language between English & Spanish
* Could send a string argument to directly pass the new language
*/
+ (void)changeCurrentLanguage
{
if ([self isCurrentLanguageEnglish]) {
[[NSUserDefaults standardUserDefaults] setObject:@[@"es"] forKey:@"AppleLanguages"];
} else {
[[NSUserDefaults standardUserDefaults] setObject:@[@"en"] forKey:@"AppleLanguages"];
}
}
@end
Gunakan kelas di atas untuk referensi file string / gambar / video / dll:
// Access a localized image
[[OSLocalization currentLanguageBundle] pathForResource:@"my_image_name.png" ofType:nil]
// Access a localized string from Localizable.strings file
NSLocalizedStringFromTableInBundle(@"StringKey", nil, [OSLocalization currentLanguageBundle], @"comment")
Ubah bahasa in-line seperti di bawah ini atau perbarui metode "changeCurrentLanguage" di kelas di atas untuk mengambil parameter string yang mereferensikan bahasa baru.
[[NSUserDefaults standardUserDefaults] setObject:@[@"es"] forKey:@"AppleLanguages"];
Di swift 4, saya telah menyelesaikannya tanpa perlu me-restart atau menggunakan perpustakaan.
Setelah mencoba banyak opsi, saya menemukan fungsi ini, tempat Anda meneruskan stringToLocalize (dari Localizable.String, file string) yang ingin Anda terjemahkan, dan bahasa tempat Anda ingin menerjemahkannya, dan apa yang dikembalikan adalah nilai untuk String yang Anda miliki di file Strings:
func localizeString (stringToLocalize: String, language: String) -> String
{
let path = Bundle.main.path (forResource: language, ofType: "lproj")
let languageBundle = Bundle (path: path!)
return languageBundle! .localizedString (forKey: stringToLocalize, value: "", table: nil)
}
Dengan mempertimbangkan fungsi ini, saya membuat fungsi ini dalam file Swift:
struct CustomLanguage {
func createBundlePath () -> Bundle {
let selectedLanguage = //recover the language chosen by the user (in my case, from UserDefaults)
let path = Bundle.main.path(forResource: selectedLanguage, ofType: "lproj")
return Bundle(path: path!)!
}
}
Untuk mengakses dari seluruh aplikasi, dan di setiap string dari ViewControllers lainnya, alih-alih menempatkan:
NSLocalizedString ("StringToLocalize", comment: “")
Saya telah menggantinya dengan
let customLang = CustomLanguage() //declare at top
let bundleLanguage = customLang.createBundle()
NSLocalizedString("StringToLocalize", tableName: nil, bundle: bundleLanguage, value: "", comment: “”) //use in each String
Saya tidak tahu apakah itu cara terbaik, tetapi saya menemukannya sangat sederhana, dan itu bekerja untuk saya, saya harap ini membantu Anda!
Fungsi ini akan mencoba untuk mendapatkan string terlokalisasi untuk bahasa saat ini dan jika tidak ditemukan itu akan mendapatkannya menggunakan bahasa inggris.
- (NSString*)L:(NSString*)key
{
static NSString* valueNotFound = @"VALUE_NOT_FOUND";
static NSBundle* enBundle = nil;
NSString* pl = [NSLocale preferredLanguages][0];
NSString* bp = [[NSBundle mainBundle] pathForResource:pl ofType:@"lproj"];
NSBundle* b = [NSBundle bundleWithPath:bp];
NSString* s = [b localizedStringForKey:key value:valueNotFound table:nil];
if ( [s isEqualToString:valueNotFound] ) {
if ( !enBundle ) {
bp = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
enBundle = [NSBundle bundleWithPath:bp];
}
s = [enBundle localizedStringForKey:key value:key table:nil];
}
return s;
}
Saya ingin menambahkan dukungan untuk bahasa yang tidak secara resmi didukung oleh iOS (tidak tercantum di bagian Bahasa di bawah pengaturan sistem). Dengan mengikuti Tutorial Internasionalisasi Apple dan beberapa petunjuk di sini oleh Brian Webster dan geon, saya membuat potongan kode ini (letakkan di main.m):
int main(int argc, char * argv[]) {
@autoreleasepool {
// Grab regional settings locale, for Slovenian this is either sl_SI or en_SI
NSLocale *locale = [NSLocale currentLocale];
NSString *ll = [locale localeIdentifier]; // sl_SI
// Grab the first part of language identifier
NSArray *comp = [ll componentsSeparatedByString:@"_"];
NSString *ll1 = @"en";
if (comp.count > 0) {
ll1 = comp[0]; // sl, en, ...
}
// Check if we already saved language (user can manually change it inside app for example)
if (![[NSUserDefaults standardUserDefaults] objectForKey:@"SelectedLanguage"]) {
// Slovenian (Slovenia), Slovenia
if ([ll isEqualToString:@"sl_SI"] || [ll isEqualToString:@"en_SI"]) {
ll1 = @"sl-SI"; // This is the part of localized path for Slovenian language that Xcode generates
}
// Add more unsupported languages here...
[[NSUserDefaults standardUserDefaults] setObject:ll1 forKey:@"SelectedLanguage"]; // Save language
}
else {
// Restore language as we have previously saved it
ll1 = [[NSUserDefaults standardUserDefaults] objectForKey:@"SelectedLanguage"];
}
// Overwrite NSLocalizedString and StoryBoard language preference
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:ll1, @"en", @"fr", nil] forKey:@"AppleLanguages"];
// Make sure settings are stored to disk
[[NSUserDefaults standardUserDefaults] synchronize];
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
Ini berfungsi baik untuk Storyboard dan kode NSLocalizedString. Kode ini mengasumsikan bahwa pengguna akan memiliki opsi untuk mengubah bahasa di dalam aplikasi secara manual nanti.
Tentu saja, jangan lupa menambahkan terjemahan Storyboard yang tepat dan terjemahan Localizable.strings (lihat tautan ke halaman Apple di atas untuk mengetahui cara melakukannya).
Berikut ini adalah solusi yang layak untuk masalah ini, dan tidak memerlukan restart aplikasi.
https://github.com/cmaftuleac/BundleLocalization
Implementasi ini bekerja dengan mengubah di dalam NSBundle. Idenya adalah bahwa Anda menimpa metode localizedStringForKey pada instance objek NSBundle, dan kemudian memanggil metode ini pada bundel berbeda dengan bahasa yang berbeda. Sederhana dan elegan sepenuhnya kompatibel dengan semua jenis sumber daya.
NSString *path = [[NSBundle mainBundle] pathForResource:lang ofType:@"lproj" ];
apa pun yang Anda semua lakukan, cara terbaik adalah mengambil nama_pendek untuk bahasa yang ditentukan, yaitu: fr, en, nl, de, it, dll ... dan tetapkan hal yang sama ke nilai global.
membuat tampilan pemilih untuk muncul seperti menu drop down (kombinasi tombol pada klik yang mana tampilan pemilih muncul dari bawah dengan daftar bahasa) dan pilih bahasa yang Anda inginkan. biarkan nama pendek disimpan secara internal. buat file .h + .m bernama LocalisedString.
Tetapkan nilai global short_name menjadi sama dengan nilai yang diperoleh di LocalisedString.m. Ketika bahasa yang diperlukan dipilih menetapkan NSBundlePath untuk membuat sub-direktori proyek untuk bahasa yang dibutuhkan. untuk misalnya, nl.proj, en.proj.
Ketika folder proj tertentu dipilih, panggil string yang dilokalisasi untuk bahasa masing-masing dan ubah bahasa secara dinamis.
tidak ada aturan yang dilanggar.
Untuk Swift Anda dapat mengganti main.swift
file dan mengatur string UserDefaults di sana sebelum aplikasi Anda berjalan. Dengan cara ini Anda tidak perlu memulai ulang Aplikasi untuk melihat efek yang diinginkan.
import Foundation
import UIKit
// Your initialisation code here
let langCultureCode: String = "LANGUAGE_CODE"
UserDefaults.standard.set([langCultureCode], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()
UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))
dipasangkan bersama dengan penghapusan @UIApplicationMain
di AppDelegate.swift
file Anda .