I want to keep my app in one of the regions and I want to localize the app without changing the native language or region settings, specifically for iOS 9, is there any way to localize the app without changing ios system settings?
[NSBundle setLanguage:#"ar"];
in the main.m before #autoreleasepool
#import "NSBundle+Language.h"
#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
Related
I want to change my app language at runtime. For that I had implemented the category class like
.h file.
#interface NSBundle (Language)
+ (void)setLanguage:(NSString *)language;
#end
.m file
#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);
[[NSNotificationCenter defaultCenter] postNotificationName:#"changeLanguage" object:self];
}
and at button click change the language like [NSBundle setLanguage:langCode];
but now I am bit confusing that what should I write to set label text like
lbl.text = ?
because it still need to restart my app to show effect of language .
iOS already have a localization file for multiple languages, you can find it in Localization/Localizable.strings.
In Localizable.strings (English)
"text" = "This is a text";
Then, put your setting text code in a function. So that, you can redraw the text after switching language.
func loadText() {
lbl.text = String.localizedString("text")
}
func changeLanguage() { // Change Language Notification
loadText()
}
I have created .plist where I put string which is used for google analytics and the problem is that the string can't be pass to that code in appdelegate.m where is google analytics code.
configuration.plist looks like this :
GAnalytics , string , "XXXXXXXX"
I have create the .h and .m file for it to read it
configuration.h
#import <Foundation/Foundation.h>
#interface Configuration : NSObject
+(instancetype)sharedConfig;
-(NSString *)GoogleAnalyticsID;
#end
configuration.m
#import "Configuration.h"
#interface Configuration ()
#property (strong, nonatomic) NSDictionary *config;
#end
#implementation Configuration
+(instancetype)sharedConfig
{
static Configuration *instance = nil;
if (!instance) {
instance = [[Configuration alloc] init];
}
return instance;
}
-(instancetype)init
{
self = [super init];
if (self) {
NSBundle *bundle = [NSBundle mainBundle];
NSString *configPath = [bundle pathForResource:#"Configuration" ofType:#"plist"];
self.config = [NSDictionary dictionaryWithContentsOfFile:configPath];
}
return self;
}
-(NSString *)GoogleAnalyticsID
{
return self.config[#"GAnalytics"];
}
#end
appdelegate.m
[GAI sharedInstance].trackUncaughtExceptions = YES;
[GAI sharedInstance].dispatchInterval = 20;
[[GAI sharedInstance] trackerWithTrackingId: [[Configuration sharedConfig] GoogleAnalyticsID]];
I making a simple soundboard and I'm trying to make my button make a sound when pressed, but when I run the simulator nothing plays. This is my code -
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(IBAction)sound1 {
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"sound1", CFSTR("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
ViewController.h
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#interface ViewController : UIViewController
-(IBAction)sound1;
#end
and also how to I link up the button up with the sound??
First, don't use wav as it takes up too much memory, mp3 is better. Second this has got nothing to do with Xcode 6. Third you may have not imported the AudioToolBox file in your linked frameworks and Libraries.
Do this in the .h file
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#interface ViewController : UIViewController
{
IBOutlet UIButton *SoundButton;
}
#end
Do This is the .m file
-(IBAction)Sound:(id)sender
{
NSLog("Button is pressed");
NSString *over = #"sound1";
SystemSoundID soundID;
NSString *soundPath = [[NSBundle mainBundle] pathForResource:over ofType:#"wav"];
NSURL *soundUrl = [NSURL fileURLWithPath:soundPath];
AudioServicesCreateSystemSoundID ((__bridge CFURLRef)soundUrl, &soundID);
AudioServicesPlaySystemSound(soundID);
}
-(void)viewDidLoad
{
[super viewDidLoad];
SoundButton = [UIButton buttonWithType:UIButtonTypeCustom];
SoundButton.frame = CGRectMake(X cord, Y cord, width, height);
[SoundButton addTarget:self action:#selector(Sound:) forControlEvents:UIControlEventTouchUpInside];
}
I advise you to learn and how to use Xcode and Objective-C / Swift before asking questions such as these.
When running my program on a iOS simulator I didn't have a problem. But when running on my iPhone5c, I have a problem. The problem is data will be destroyed when the data was loaded. Here is my program source code. Where my code is wrong?
overview of my program:
1.load data from "sample.txt"
2.log the data
AppDelegate.h:
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (assign) unsigned char* bytePtr;
#property (strong, nonatomic) NSData* data;
#end
AppDelegate.m:
#import "AppDelegate.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
[self load];
return YES;
}
- (void) load
{
NSString* path = [[NSBundle mainBundle] pathForResource:#"sample" ofType:#"txt"];
self.data = [NSData dataWithContentsOfFile:path];
self.bytePtr = (unsigned char *)[self.data bytes];
NSLog(#"%s", self.bytePtr);
}
~snip~
sample.txt:
abcdefghijklmnopqrstuvwxyz
output:
abcdefghijklmnopqrstuvwxyz
roj
expected output:
abcdefghijklmnopqrstuvwxyz
NSString* path = [[NSBundle mainBundle] pathForResource:#"sample" ofType:#"txt"];
self.data = [NSData dataWithContentsOfFile:path];
self.bytePtr = (unsigned char *)[self.data bytes];
NSLog(#"%s", self.bytePtr);
You're accessing data as though it is a NULL-terminated cstring (using %s). Unless your file ends in a \0 (which is doesn't appear to), your NSLog will just keep reading data until it finds one.
If you want to read a string from a file, using stringWithContentsOfURL:encoding:error:.
want to add a possibility to change language in application in my app, so when the current iPhone language is English. but user set turkish in app for my application I have to force my application to localize in turkish.
i am already add file to setLanguage
LocalizationSystem.h
LocalizationSystem.m
on button Action i write given below code:
if([sender tag]==0)
{
LocalizationSetLanguage(#"en");
NSString * currentL = LocalizationGetLanguage;
NSLog(#"currentL EN:%#",currentL);
}
else
{
LocalizationSetLanguage(#"tr");
NSString * currentL = LocalizationGetLanguage;
NSLog(#"currentL TR:%#",currentL);
}
this code doesn't change language. In both NSLog it prints give below line:
2014-09-11 15:54:30.640 uyarbeni[6480:70b] currentL EN:en
2014-09-11 15:54:30.640 uyarbeni[6480:70b] currentL TR:en
when i look through the code in LocalizationSystem.m file
- (void) setLanguage:(NSString*) l
{
NSLog(#"preferredLang: %#", l);
NSString *path = [[ NSBundle mainBundle ] pathForResource:l ofType:#"lproj" ];
if (path == nil)
[self resetLocalization];
else
bundle = [NSBundle bundleWithPath:path] ;
}
Please Help me to solve the problem.
But When i select language from device setting then language get change.
You will have to set property in #"AppleLanguages" to have the selected language code by setting it via NSUserDefaults.
Like so:
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:<your code>, nil] forKey:#"AppleLanguages"];
I use it in my application, to change language use: [NSBundle setLanguage:#"tr"];
To use localized resources: [[NSBundle localBundle] pathForResource:#"List" ofType:#"plist"];
Import header in ProjectName-Prefix.pch
//.h
#import <Foundation/Foundation.h>
#interface NSBundle (Language)
+ (NSBundle *)localBundle;
+ (void)setLanguage:(NSString*)language;
#end
//.m
#import "NSBundle + Language.h"
#import <objc/runtime.h>
NSString *currentLanguage;
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)
+ (NSBundle *)localBundle
{
if (currentLanguage)
{
NSString *path = [[NSBundle mainBundle] pathForResource:currentLanguage ofType:#"lproj"];
return [NSBundle bundleWithPath:path];
}
else
{
return [NSBundle mainBundle];
}
}
+(void)setLanguage:(NSString*)language
{
currentLanguage = 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