IPhone पर iPhone NSLocalizedString
की भाषा में स्ट्रिंग लौटाता है। क्या NSLocalizedString
डिवाइस से अलग भाषा में एप्लिकेशन के लिए एक विशिष्ट भाषा का उपयोग करने के लिए मजबूर करना संभव है?
IPhone पर iPhone NSLocalizedString
की भाषा में स्ट्रिंग लौटाता है। क्या NSLocalizedString
डिवाइस से अलग भाषा में एप्लिकेशन के लिए एक विशिष्ट भाषा का उपयोग करने के लिए मजबूर करना संभव है?
जवाबों:
NSLocalizedString()
(और इसके प्रकार) "AppleLanguages" कुंजी को एक्सेस करते हैं NSUserDefaults
पसंदीदा भाषाओं के लिए उपयोगकर्ता की सेटिंग्स क्या हैं, यह निर्धारित करने के । यह भाषा कोड की एक सरणी देता है, जिसमें पहले एक को उपयोगकर्ता द्वारा अपने फोन के लिए सेट किया जाता है, और बाद के लोगों को पसंदीदा भाषा में एक संसाधन उपलब्ध नहीं होने पर कमियां के रूप में उपयोग किया जाता है। (डेस्कटॉप पर, उपयोगकर्ता सिस्टम वरीयताएँ में कस्टम ऑर्डर के साथ कई भाषाओं को निर्दिष्ट कर सकता है)
आप अपने स्वयं के अनुप्रयोग के लिए वैश्विक सेटिंग को ओवरराइड कर सकते हैं यदि आप setObject का उपयोग करके चाहें: forKey: अपनी भाषा सूची सेट करने की विधि। यह विश्व स्तर पर निर्धारित मूल्य पर पूर्वता लेगा और आपके आवेदन में किसी भी कोड पर वापस आ जाएगा जो स्थानीयकरण कर रहा है। इसके लिए कोड कुछ इस तरह दिखेगा:
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"de", @"en", @"fr", nil] forKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize]; //to make the change immediate
यह जर्मन को आपके आवेदन के लिए पसंदीदा भाषा बना देगा, जिसमें अंग्रेजी और फ्रेंच में कमियां होंगी। आप इसे अपने एप्लिकेशन के स्टार्टअप में कुछ समय पहले कॉल करना चाहेंगे। आप यहां भाषा / स्थानीय प्राथमिकताओं के बारे में अधिक पढ़ सकते हैं: अंतर्राष्ट्रीयकरण प्रोग्रामिंग विषय: वर्तमान भाषा और स्थान प्राप्त करना
मुझे हाल ही में यही समस्या थी और मैं अपना पूरा NSLocalizedString शुरू और पैच नहीं करना चाहता था न ही ऐप को नई भाषा को काम करने के लिए फिर से शुरू करने के लिए मजबूर कर । मैं चाहता था कि सब कुछ जैसे भी हो, मैं काम करूं।
मेरा समाधान मुख्य बंडल की कक्षा को गतिशील रूप से बदलना और वहां उपयुक्त बंडल को लोड करना था:
शीर्ष लेख फ़ाइल
@interface NSBundle (Language)
+(void)setLanguage:(NSString*)language;
@end
कार्यान्वयन
#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
इसलिए मूल रूप से, जब आपका ऐप शुरू होता है और इससे पहले कि आप अपना पहला नियंत्रक लोड करें, बस कॉल करें:
[NSBundle setLanguage:@"en"];
जब आपका उपयोगकर्ता आपकी सेटिंग स्क्रीन में अपनी पसंदीदा भाषा बदलता है, तो बस उसे फिर से कॉल करें:
[NSBundle setLanguage:@"fr"];
सिस्टम डिफॉल्ट्स पर वापस जाने के लिए, बस nil पास करें:
[NSBundle setLanguage:nil];
का आनंद लें...
उन लोगों के लिए जिन्हें स्विफ्ट संस्करण की आवश्यकता है:
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)
}
}
मैं आमतौर पर इस तरह से करता हूं, लेकिन आपके पास अपने प्रोजेक्ट में सभी स्थानीयकरण फ़ाइलें होनी चाहिए।
@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
आईओएस 9 पर उपयोग न करें। यह सभी तारों से गुजरता है।
मुझे एक और उपाय मिला है जिससे आप भाषा के तार को अपडेट कर सकते हैं, w / o ऐप को फिर से शुरू कर सकते हैं और जेनस्ट्रिंग्स के साथ संगत कर सकते हैं:
इस मैक्रो को Prefix.pch में डालें:
#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]
और जहां कभी आपको स्थानीयकृत स्ट्रिंग उपयोग की आवश्यकता होती है:
NSLocalizedStringFromTableInBundle(@"GalleryTitleKey", nil, currentLanguageBundle, @"")
भाषा का उपयोग निर्धारित करने के लिए:
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];
यहां तक कि लगातार भाषा के साथ काम करता है जैसे:
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, @""));
जैसा कि पहले कहा गया था, बस करो:
[[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:@"el", nil] forKey:@"AppleLanguages"];
लेकिन ऐप को पुनरारंभ करने से बचने के लिए, मुख्य विधि में लाइन डालें main.m
, बस UIApplicationMain
(...) से पहले ।
NSAutoreleasePool * pool ..
या कुछ ऑटोरेल्ड ऑब्जेक्ट लीक हो जाएंगे।
[[NSBundle mainBundle] URLForResource:withExtension:]
पहले फोन करते हैं तो यह काम नहीं करेगा ।
एप्लिकेशन से इसे चुनकर विशिष्ट भाषा का उपयोग करने की चाल को मजबूर करना है NSLocalizedString
, चयनित भाषा के आधार पर विशिष्ट बंडल का उपयोग करने के है,
यहाँ ios ऐप्स में इस सीखने के अग्रिम स्थानीयकरण के लिए पोस्ट लिखी गई है
और यहाँ ios ऐप्स में एक नमूना एप्लिकेशन अग्रिम स्थानीयकरण का कोड है
स्विफ्ट 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)
}
}
सरल उपयोग:
"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.
जैसा कि ब्रायन वेबस्टर का उल्लेख है, भाषा को "आपके एप्लिकेशन के स्टार्टअप में कुछ समय पहले" सेट करने की आवश्यकता है। मैंने सोचा था कि applicationDidFinishLaunching:
की AppDelegate
यह करने के लिए एक उपयुक्त जगह होना चाहिए, क्योंकि यह है जहाँ मैं सभी अन्य प्रारंभ करते हैं।
लेकिन जैसा कि विलियम डेनिस का उल्लेख है, ऐसा लगता है कि ऐप के दोबारा शुरू होने के बाद ही इसका असर होगा , जो बेकार है।
यदि मैं मुख्य कार्य में कोड डालता हूँ तो यह ठीक काम करता है, हालाँकि:
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;
}
मैं इस पर किसी भी टिप्पणी की सराहना करता हूँ।
[[NSUserDefaults standardUserDefaults] synchronize];
कॉल करने के बाद उपयोग करेंsetObject:forKey:
मुझे सबसे अच्छी मौरो डेलारियो की विधि पसंद है। मैंने अपने Project_Prefix.pch में निम्नलिखित को भी जोड़ा है
#import "Language.h"
#define MyLocalizedString(key, alt) [Language get:key alter:alt]
इसलिए यदि आप कभी भी मानक विधि का उपयोग करना चाहते हैं (जो NSLocalizedString का उपयोग करता है) तो आप सभी फाइलों में एक त्वरित वाक्यविन्यास प्रतिस्थापन कर सकते हैं।
NSLocalizedString()
AppleLanguages
मानक उपयोगकर्ता डिफ़ॉल्ट ( [NSUserDefaults standardUserDefaults]
) से कुंजी के लिए मान पढ़ता है । यह रनटाइम पर सभी मौजूदा स्थानीयकरणों के बीच एक उपयुक्त स्थानीयकरण चुनने के लिए उस मूल्य का उपयोग करता है। जब ऐप्पल लॉन्च के दौरान ऐप्पल उपयोगकर्ता डिफॉल्ट्स डिक्शनरी बनाता है, तो वे सिस्टम वरीयताओं में पसंदीदा भाषा (एस) कुंजी को देखते हैं और वहां से मूल्य कॉपी करते हैं। यह भी उदाहरण के लिए बताता है कि ओएस एक्स में भाषा सेटिंग्स को बदलने से ऐप चलाने पर कोई प्रभाव नहीं पड़ता है, केवल इसके बाद शुरू होने वाले ऐप पर। एक बार कॉपी करने के बाद, मूल्य केवल इसलिए अपडेट नहीं किया जाता है क्योंकि सेटिंग्स बदल जाती हैं। इसलिए iOS सभी ऐप्स को पुनरारंभ करता है यदि आप बदलते हैं तो भाषा।
हालाँकि, उपयोगकर्ता डिफॉल्ट्स डिक्शनरी के सभी मूल्यों को कमांड लाइन तर्कों द्वारा अधिलेखित किया जा सकता है। NSUserDefaults
पर प्रलेखन देखें NSArgumentDomain
। यहां तक कि उन मानों को भी शामिल किया गया है जो ऐप वरीयताओं (.plist) फ़ाइल से लोड किए गए हैं। यह जानना वास्तव में अच्छा है कि क्या आप परीक्षण के लिए सिर्फ एक बार मूल्य बदलना चाहते हैं ।
इसलिए यदि आप केवल परीक्षण के लिए भाषा बदलना चाहते हैं, तो आप शायद अपने कोड को बदलना नहीं चाहते हैं (यदि आप बाद में इस कोड को हटाना भूल जाते हैं ...), इसके बजाय Xcode को कमांड लाइन मापदंडों के साथ अपना ऐप शुरू करने के लिए कहें ( उदाहरण के लिए स्पेनिश स्थानीयकरण का उपयोग करें):
अपने कोड को छूने की कोई आवश्यकता नहीं है। बस अलग-अलग भाषाओं के लिए अलग-अलग योजनाएं बनाएं और आप केवल एक बार एक भाषा में और एक बार दूसरे में केवल योजना को स्विच करके ऐप को शुरू कर सकते हैं।
Options
नए Xcode संस्करणों के साथ भाषा को ओवरराइड नहीं करते हैं, Apple ऑफर करता है कि भी।
मैं एक समाधान के साथ आया था जो आपको उपयोग करने की अनुमति देता है NSLocalizedString
। मैं NSBundle
कॉल की एक श्रेणी बनाता हूं NSBundle+RunTimeLanguage
। इंटरफ़ेस इस तरह है।
// 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
कार्यान्वयन इस तरह है।
// 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
केवल NSBundle+RunTimeLanguage.h
उन फ़ाइलों में आयात जोड़ें जो उपयोग करती हैं NSLocalizedString
।
जैसा कि आप देख सकते हैं कि मैं अपनी भाषा को एक संपत्ति में संग्रहीत करता हूं AppDelegate
। इसे आप कहीं भी संग्रहीत कर सकते हैं।
यह केवल एक चीज है जो मुझे पसंद नहीं है यह एक चेतावनी है जिसे NSLocalizedString
मार्को ने फिर से परिभाषित किया है। शायद कोई मुझे इस हिस्से को ठीक करने में मदद कर सकता है।
#undef NSLocalizedString
से ठीक पहले जोड़ें#define
यह पहला काम है जो आपको अपने ऐप को कम से कम दो भाषाओं (इस उदाहरण में अंग्रेजी और फ्रेंच) के साथ करना है।
अपने कोड में, उपयोग करने के बजाय NSLocalizedString(key, comment)
, MYLocalizedString(key, comment)
इस तरह परिभाषित एक मैक्रो का उपयोग करें:
#define MYLocalizedString(key, comment) [[MYLocalizationSystem sharedInstance] localizedStringForKey:(key) value:(comment)];
यह MYLocalizationSystem
सिंगलटन होगा:
जब उपयोगकर्ता ने फ्रेंच में एप्लिकेशन भाषा बदली, तो कॉल करें [[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];
}
इस उदाहरण में इस विधि ने स्थानीयकृत बंडल को fr.lproj पर सेट किया है
एक बार स्थानीयकृत बंडल सेट करने के बाद, आप इस विधि से उससे सही स्थानीयकृत स्ट्रिंग प्राप्त कर सकेंगे:
- (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];
}
आशा है कि यह आपकी मदद करेगा।
आप इस लेख में NSWinery.io से अधिक जानकारी प्राप्त करेंगे
स्विफ्ट 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
}
}
उपयोग:
Locale.preferredLanguage = "uk"
label.text = "localizedKey".localized
फ़ाइल .pch में परिभाषित करने के लिए:
#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]
#define NSLocalizedString(str,nil) NSLocalizedStringFromTableInBundle(str, nil, currentLanguageBundle, @"")
शायद आपको इसके साथ पूरक होना चाहिए (#import के बाद .pch फ़ाइल पर):
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]
स्विफ्ट 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")
भाषा कोड के कुछ उदाहरण दिए गए जिनका उपयोग किया जा सकता है। उम्मीद है की यह मदद करेगा
आप स्थानीय स्ट्रिंग्स के सेट के साथ एक उप-बंडल बना सकते हैं जिसे आप इसके साथ करना चाहते हैं, और फिर NSLocalizedStringFromTableInBundle()
उन्हें लोड करने के लिए उपयोग करें। (मैं मान रहा हूं कि यह सामान्य यूआई स्थानीयकरण से अलग है जो आप ऐप पर कर रहे हैं।
मेरे मामले में मेरे पास दो स्थानीय फ़ाइल, ja और en हैं
और मैं इसे लागू करने के लिए बाध्य करना चाहूंगा अगर सिस्टम में पसंदीदा भाषा न तो एन या जेए
मैं main.m फ़ाइल को संपादित करने जा रहा हूँ
मैं जाँच करूँगा कि क्या पहली पसंद एन या ja है, अगर नहीं तो मैं दूसरी पसंदीदा भाषा को बदलूँगा।
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]));
}
}
आप ऐसा कुछ कर सकते हैं:
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Localizable" ofType:@"strings" inDirectory:nil forLocalization:@"es"];
NSBundle *spanishBundle = [[NSBundle alloc] initWithPath:[bundlePath stringByDeletingLastPathComponent]];
NSLocalizedStringFromTableInBundle(@"House", nil, spanishBundle, nil):
आवेदन छोड़ने या पुनः आरंभ किए बिना भाषा बदलने के लिए ट्यूडराइज़र के उत्तर के आधार पर ।
मैक्रो के बजाय, एक विशिष्ट भाषा कोड मौजूद है या नहीं यह जांचने के लिए पसंदीदा भाषा तक पहुंचने के लिए एक वर्ग का उपयोग करें।
नीचे वर्तमान भाषा बंडल को प्राप्त करने के लिए उपयोग किया जाने वाला एक वर्ग है जो 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
एक स्ट्रिंग फ़ाइल / छवि / वीडियो / आदि को संदर्भित करने के लिए उपरोक्त वर्ग का उपयोग करें:
// 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")
नीचे की तरह भाषा को इन-लाइन में बदलें या नई भाषा को संदर्भित करने वाले एक स्ट्रिंग पैरामीटर लेने के लिए ऊपर दिए गए वर्ग में "चेंजकार्टल लैंग्वेज" विधि को अपडेट करें।
[[NSUserDefaults standardUserDefaults] setObject:@[@"es"] forKey:@"AppleLanguages"];
स्विफ्ट 4 में, मैंने इसे फिर से शुरू करने या पुस्तकालयों का उपयोग करने की आवश्यकता के बिना हल किया है।
कई विकल्पों को आज़माने के बाद, मुझे यह फ़ंक्शन मिला, जहाँ आप stringToLocalize (of Localizable.String, स्ट्रिंग्स फ़ाइल) जिसे आप अनुवाद करना चाहते हैं, और जिस भाषा में आप इसका अनुवाद करना चाहते हैं, और जो रिटर्न देता है, वह मान है स्ट्रिंग जो आपके पास स्ट्रिंग्स फ़ाइल में है:
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)
}
इस फ़ंक्शन को ध्यान में रखते हुए, मैंने एक स्विफ्ट फ़ाइल में यह फ़ंक्शन बनाया:
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!)!
}
}
पूरे ऐप से, और बाकी ViewControllers के प्रत्येक तार में डालने के बजाय:
NSLocalizedString ("StringToLocalize", comment: “")
मैंने इसे बदल दिया है
let customLang = CustomLanguage() //declare at top
let bundleLanguage = customLang.createBundle()
NSLocalizedString("StringToLocalize", tableName: nil, bundle: bundleLanguage, value: "", comment: “”) //use in each String
मुझे नहीं पता कि यह सबसे अच्छा तरीका है, लेकिन मुझे यह बहुत सरल लगा, और यह मेरे लिए काम करता है, मुझे आशा है कि यह आपकी मदद करता है!
यह फ़ंक्शन वर्तमान भाषा के लिए स्थानीयकृत स्ट्रिंग प्राप्त करने का प्रयास करेगा और अगर यह नहीं मिला है तो इसे अंग्रेजी भाषा का उपयोग करके मिलेगा।
- (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;
}
मैं ऐसी भाषा के लिए समर्थन जोड़ना चाहता था जो आधिकारिक रूप से iOS द्वारा समर्थित नहीं है (सिस्टम सेटिंग्स के तहत भाषा अनुभाग में सूचीबद्ध नहीं है)। का पालन करके एप्पल के अंतर्राष्ट्रीयकरण ट्यूटोरियल ब्रायन वेबस्टर और geon द्वारा यहां और कुछ संकेत, मैं कोड (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]));
}
}
यह स्टोरीबोर्ड और NSLocalizedString कोड दोनों के लिए अच्छा काम करता है। कोड मानता है कि उपयोगकर्ता के पास बाद में ऐप के अंदर भाषा को मैन्युअल रूप से बदलने का विकल्प होगा।
बेशक, उचित स्टोरीबोर्ड अनुवाद और Localizable.strings अनुवाद जोड़ने के लिए मत भूलना (कैसे करने के लिए ऊपर Apple पृष्ठ के लिए लिंक देखें)।
यहां इस समस्या का एक सभ्य समाधान है, और इसके लिए एप्लिकेशन पुनरारंभ की आवश्यकता नहीं है।
https://github.com/cmaftuleac/BundleLocalization
यह कार्यान्वयन NSBundle के अंदर ट्विक करके काम करता है। विचार यह है कि आप NSBundle ऑब्जेक्ट के उदाहरण पर स्थानीयकृतStringForKey विधि को ओवरराइड करते हैं, और फिर एक अलग भाषा के साथ एक अलग बंडल पर इस विधि को कॉल करते हैं। सभी प्रकार के संसाधनों के साथ सरल और सुरुचिपूर्ण पूरी तरह से संगत।
NSString *path = [[NSBundle mainBundle] pathForResource:lang ofType:@"lproj" ];
आप सभी जो भी करते हैं, सबसे अच्छा तरीका है कि निर्दिष्ट भाषा के लिए short_name लेना है, अर्थात: fr, en, nl, de, it, etc ... और इसे वैश्विक मान के लिए असाइन करें।
एक ड्रॉप डाउन मेनू की तरह पॉप अप करने के लिए एक पिकर दृश्य बनाएं (जिस पर क्लिक करने पर एक बटन का संयोजन भाषाओं की सूची के साथ नीचे से प्रकट होता है) और उस भाषा का चयन करें जिसे आप चाहते हैं। संक्षिप्त नाम को आंतरिक रूप से संग्रहीत किया जाए। स्थानीयकृतस्ट्रिंग नामक .h + .m फ़ाइल बनाएँ
Local_String.m में प्राप्त मान के बराबर होने के लिए short_name का वैश्विक मान सेट करें। आवश्यक भाषा चयनित होने पर आवश्यक भाषा के लिए प्रोजेक्ट उप-निर्देशिका बनाने के लिए NSBundlePath असाइन करें। उदाहरण के लिए, nl.proj, en.proj।
जब विशेष प्रोज फ़ोल्डर का चयन किया जाता है, तो संबंधित भाषा के लिए स्थानीय स्ट्रिंग को कॉल करें और भाषा को गतिशील रूप से बदलें।
कोई नियम नहीं तोड़ा।
स्विफ्ट के लिए आप main.swift
फ़ाइल को ओवरराइड कर सकते हैं और ऐप के चलने से पहले UserDefaults स्ट्रिंग को वहां सेट कर सकते हैं । इस तरह आपको वांछित प्रभाव देखने के लिए ऐप को पुनरारंभ करने की आवश्यकता नहीं है।
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))
@UIApplicationMain
आपकी AppDelegate.swift
फ़ाइल को निकालने के साथ जोड़ा गया ।