6

As in this question, How to force NSLocalizedString to use a specific language

I can force localise by this method.

Header file

@interface NSBundle (Language)
+(void)setLanguage:(NSString*)language;
@end

Implementation

#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

After that, I need to localise image and as a result, I do like this. Localize Asset Catalogs

Problem is when I change localisation programmatically, it never change image.

 [NSBundle setLanguage:@"en"];

Only my string are changed. How shall I do? I have tried with both normal image and image in assets like this. But it doesn't work unless I really change my phone language in setting. But I need to change/force localisation programmatically and image need to be changed (not only text). May I know how to do?

enter image description here

Community
  • 1
  • 1
Khant Thu Linn
  • 5,905
  • 7
  • 52
  • 120

1 Answers1

1

I know that is an old question but still answering for future reference.


Make sure that you set your app language in the main.m, it works like a charm for the images.

OBS : Not using xcassets.

Like this:

int main(int argc, char * argv[])
{
    @autoreleasepool
    {
        NSString *language = <Get Your Language from somewhere> // I user NSUserDefaults for that

        if (language == nil)
        {
            // Gets the device current language
            language = [[[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0] substringToIndex:2];
        }

        [NSBundle setLanguage:language];

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([YourAppDelegate class]));
    }
}

Additionally I have this method on the BundleEx implementation. It is not needed for the localized images but I needed it for .html templates I had, for instance.

- (NSString *)pathForResource:(NSString *)name ofType:(NSString *)ext
{
    NSBundle *bundle = objc_getAssociatedObject(self, &_bundle);

    NSString *pathName = [bundle pathForResource:name ofType:ext];
    return pathName ?: [super pathForResource:name ofType:ext];
}
Otávio
  • 735
  • 11
  • 23
  • can i get language from service? if yes how to do it – Mourice May 16 '16 at 09:25
  • @Mourice did not get your question. What are you trying to solve? – Otávio May 16 '16 at 13:58
  • my laguage code is defined at server side. so i want to hit the service get the laguage code and set it. I am doing the web service call inside main but setting the laguage code not reflecting. Only changes after second run – Mourice May 16 '16 at 14:11
  • @Mourice I assume your call is done in a async well, so the main hits the `return` before your call to the webservice finishes. I would suggest to rethink your approach and if you still having problems create a new question and link it here since your problem has nothing to do witth the original question. – Otávio May 16 '16 at 14:53