GMSGeocoder - how to set response language - ios

When using my app in a foreign country, the google GMSGeocoder is returning the response in local language automatically. how can I set it to always return the the response in English?
Im using GMS SDK 1.7 and my code is something like this:
GMSGeocoder *geoCoder = [[GMSGeocoder alloc] init];
[geoCoder reverseGeocodeCoordinate:self.cellLocation.coordinate completionHandler:^(GMSReverseGeocodeResponse *respones, NSError *err) {
if([respones firstResult]) {
GMSAddress* address = [respones firstResult];
NSString* fullAddress = [NSString stringWithFormat:#"%#, %#",address.thoroughfare, address.locality];
self.theTextField.text = fullAddress;
} else {
self.theTextField.text = #"";
}
}];

Using a GMSGeocoder category can solve this issue, inspired by #DaNLtR
After that , It can set geocoder result as English .
#implementation GMSGeocoder (Load)
+(void)load {
[[self class] setUserLanguage:#"en-CN"];// set your wanted language.
NSLog(#"GMSGeocoder + load!");
}
- (void)dealloc {
[[self class] resetSystemLanguage];
NSLog(#"GMSGeocoder + dealloc!");
}
+ (void)setUserLanguage:(NSString *)userLanguage
{
if (!userLanguage.length) {
[[self class] resetSystemLanguage];
return;
}
[[NSUserDefaults standardUserDefaults] setValue:userLanguage forKey:#"UserLanguage"];
[[NSUserDefaults standardUserDefaults] setValue:#[userLanguage] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
+ (void)resetSystemLanguage
{
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"UserLanguage"];
[[NSUserDefaults standardUserDefaults] setValue:nil forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
#end
Why should in category?
A:I tested setLanguage: before GMSGeocoder reverseGeocodeCoordinate method, it can't affect geocoder result. After I saw DaNLtR's answer , I think we can setLanguge in load method.
Why should reset language?
A:Avoide affect other module or framework .

Just change it to your language parameters
int main(int argc, char * argv[])
{
#autoreleasepool {
//For Google Maps hebrew response
//[[NSUserDefaults standardUserDefaults] setObject:#[#"en"] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] setObject:#[#"he",#"he-IL"] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

Related

Crash interacting with NSUserDefaults and NSArray

I have an NSMutableArray in which I am adding objective and storing in user defaults, but while adding it is crashing.
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"bssidObserverArray"]) {
bssidObserverArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"bssidObserverArray"];
}
if (bssidObserverArray.count > 0) {
if (![bssidObserverArray containsObject:vendorID]) {
NSLog(#"bssidObserverArray %#",bssidObserverArray);
// In this line app is getting crashed
[bssidObserverArray addObject:vendorID];
[[NSUserDefaults standardUserDefaults] setObject:bssidObserverArray forKey:#"bssidObserverArray"];
}
}else{
[bssidObserverArray addObject:vendorID];
[[NSUserDefaults standardUserDefaults] setObject:bssidObserverArray forKey:#"bssidObserverArray"];
}
Any suggestions would be more helpful.
Assuming bssidObserverArray is NSMutable array then come the problem here .
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"bssidObserverArray"]) {
bssidObserverArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"bssidObserverArray"];
}
since NSUserdefaults returns immutable. you can do like this
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"bssidObserverArray"]) {
NSArray *someArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"bssidObserverArray"];
bssidObserverArray = [someArray mutableCopy];
}

Store multiple key-value pair in NSUserDefaults

I am building a simple login and registration in IOS (xcode 6.4). To save username and password i am using NSUserDefaults. But the problem is I Can't store multiple username and passwords since I am saving data to same key.What's the alternate method to implement it.I saw some similar questions on stackoverflow but couldn't understand the solution. So can anyone explain in easy way. HEre is my code:
//function for login pressed
- (IBAction)login:(UIButton *)sender
{
NSLog(#"%#,%#",userNameField.text,passwordField.text);
username = [[NSUserDefaults standardUserDefaults] objectForKey:#"username"];
password = [[NSUserDefaults standardUserDefaults] objectForKey:#"password"];
NSLog(#"%#,%#",username,password);
bool validUser = [username isEqualToString:userNameField.text];
bool validPassword = [password isEqualToString:passwordField.text];
if ([self checkWhetherFieldIsEmpty:userNameField.text :passwordField.text])
{
[self displayAlert:#"All Fileds are mandatory"];
}
else if(validUser && validPassword)
{
[self displayAlert:#"Successfull Login"] ;
}
else{
// NSLog(#"Invalid username or password");
[self displayAlert:#"Invalid login or password"];
}
}
//function when register button is pressed
- (IBAction)register:(UIButton *)sender
{
if([[[NSUserDefaults standardUserDefaults] objectForKey:#"username"] isEqualToString:userNameField.text])
{
[self displayAlert:#"User already exist"];
userNameField.text = #"";
passwordField.text = #"";
}
else
{
[[NSUserDefaults standardUserDefaults] setObject:userNameField.text forKey:#"username"];
[[NSUserDefaults standardUserDefaults] setObject:passwordField.text forKey:#"password"];
[[NSUserDefaults standardUserDefaults]synchronize];
NSLog(#"user Created successfully");
[self displayAlert:#"Registration Successfull"];
}
}
As pointed out by Simon, there are security issues storing usernames and passwords in NSUserDefaults. If you still want to do it however, it is quite simple.
NSUserDefaults is really not much more then a plist so you can store arbitrary complex structures created from NSArray and NSDictionary in NSUserDefaults. So you can do something like:
NSArray<NSDictionary*>* accounts = #[#{
#"username" : #"firstUsername",
#"password" : #"firstPassword"
}, #{
#"username" : #"secondUsername",
"password" : #"secondPassword"
}];
[[NSUserDefaults standardUserDefaults] setObject: accounts forKey:#"accounts"];
Note that you can't change one account only; if you need to change or add a new account, you should read the whole structure, convert the array and the dictionaries to mutable variants, and re-write it to the defaults all together.
UPDATE
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray* mutableAccounts = [[defaults objectForKey:#"accounts"] mutableCopy];
// Add or remove accounts:
[mutableAccounts addObject:#{ #"username" : #"newAccount", #"password" : #"newPassword" }];
[mutableAccounts removeObjectAtIndex:0];
[defaults setObject:mutableAccounts forKey:#"accounts"];
You can simple save your password as object of key username, some think like:
- (IBAction)login:(UIButton *)sender {
NSLog(#"%#,%#",userNameField.text,passwordField.text);
NSString *password = userNameField.text.length > 0? [[NSUserDefaults standardUserDefaults] objectForKey:userNameField.text] : nil;
bool validUser = passwordField.text.length > 0 ? [passwordField.text isEqualToString:password] : NO;
if ([self checkWhetherFieldIsEmpty:userNameField.text :passwordField.text]) {
[self displayAlert:#"All Fileds are mandatory"];
}
else if(validUser){
[self displayAlert:#"Successfull Login"] ;
}
else{
// NSLog(#"Invalid username or password");
[self displayAlert:#"Invalid login or password"];
}
}
//function when register button is pressed
- (IBAction)register:(UIButton *)sender {
//TODO: need check userNameField passwordField is not nil here
if([[[NSUserDefaults standardUserDefaults] objectForKey:userNameField.text] length] > 0){
[self displayAlert:#"User already exist"];
userNameField.text = #"";
passwordField.text = #"";
}
else {
[[NSUserDefaults standardUserDefaults] setObject:passwordField.text forKey:userNameField.text];
[[NSUserDefaults standardUserDefaults]synchronize];
NSLog(#"user Created successfully");
[self displayAlert:#"Registration Successfull"];
}
}

iOS Localize app manually then switch

I have been facing a problem with iOS Programming since its the first time I'm using Localization,,
I used the following to know which lang I'm having:
- (NSString*) getLanguage{
NSArray* languages = [[NSUserDefaults standardUserDefaults] objectForKey:#"AppleLanguages"];
NSString *preferredLang = [languages objectAtIndex:0];
return preferredLang;}
and there is button to change the lang That calls function to change the lang
- (void) setLanguage:(NSString*) l{
[[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:l, nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults]synchronize];}
The language changes successfully, but I need to close and reopen the app to see the result, is there any other way to change the localisation automatically after switching lang?
NOTE: it should woke with storyboards too.
As #Tudorizer describes in this link after you translate your files
use this solution:
Put this macro in the Prefix.pch:
#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:#"lproj"]]
and where ever you need a localized string use:
NSLocalizedStringFromTableInBundle(#"GalleryTitleKey", nil, currentLanguageBundle, #"");
To set the language use:
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:#"de"] forKey:#"AppleLanguages"];
Multiple times:
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, #""));
You can switch between languages in your application using the following class:
(Note that anyway you should refresh content of all controllers stored in memory to get full effect.)
// AMLocalization.h
#define SetAppLanguage(language) [[AMLocalization sharedLocalization] setLanguage:language]
#define GetAppLanguage() [[AMLocalization sharedLocalization] language]
#define LSC(key, comment) [[AMLocalization sharedLocalization] localizedStringForKey:(key) value:(comment)]
#define UDKeyAppLanguage #"UDKeyAppLanguage"
typedef enum {
UILanguageUnknown,
UILanguageEnglish,
UILanguageFrench,
..................
} UILanguage;
#interface AMLocalization : NSObject
+ (AMLocalization *)sharedLocalization;
- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)comment;
- (BOOL) setLanguage:(UILanguage) lang;
- (UILanguage) language;
#end
// AMLocalization.m
#import "AMLocalization.h"
static AMLocalization *_s_sharedLocalization = nil;
#implementation AMLocalization {
NSBundle *_bundle;
NSDictionary *_languageSet;
}
+ (AMLocalization *)sharedLocalization
{
static dispatch_once_t once;
dispatch_once(&once, ^{
_s_sharedLocalization = [AMLocalization new];
});
return _s_sharedLocalization;
}
- (id) init
{
if (self = [super init]) {
_bundle = [NSBundle mainBundle];
_languageSet = #{
#(UILanguageEnglish) : #"en",
#(UILanguageFrench) : #"fr"
};
}
return self;
}
- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)comment
{
return [_bundle localizedStringForKey:key value:comment table:nil];
}
- (BOOL) setLanguage:(UILanguage) lang
{
UILanguage activeLang = [self language];
if (lang == UILanguageUnknown) {
_bundle = [NSBundle mainBundle];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:UDKeyAppLanguage];
}
else {
NSString *path = [[NSBundle mainBundle] pathForResource:_languageSet[#(lang)] ofType:#"lproj"];
_bundle = [NSBundle bundleWithPath:path];
[[NSUserDefaults standardUserDefaults] setInteger:lang forKey:UDKeyAppLanguage];
}
[[NSUserDefaults standardUserDefaults] synchronize];
return activeLang != lang;
}
- (UILanguage) language
{
UILanguage lang = [[NSUserDefaults standardUserDefaults] integerForKey:UDKeyAppLanguage];
if (lang == UILanguageUnknown) {
NSString* preferredLang = [[NSUserDefaults standardUserDefaults] objectForKey:#"AppleLanguages"][0];
for (NSNumber *key in _languageSet) {
if ([_languageSet[key] isEqualToString:preferredLang]) {
lang = [key integerValue];
break;
}
}
}
return lang;
}
#end

array of all languages in English - iOS

I'm trying to look for an array of all languages written specifically in English.
I've read several questions about this subject, and I noticed this line of code:
NSArray *languages = [[NSUserDefaults standardUserDefaults] objectForKey:#"AppleLanguages"];
"languages" array-object holds all langauges string, but the problem is that it's written in the language that's defined in my iPhone. I want it to be in English for all devices.
Is there a way to accomplish that?
Force the default language to be "en" then query the languages list and set it back to the previous one. Something like this (not tested thought)
NSArray *languages = [[NSUserDefaults standardUserDefaults] objectForKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"en", nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
//your query here
//restore the previous
[[NSUserDefaults standardUserDefaults] setObject:languages forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSArray *localIdentifiers = [NSLocale availableLocaleIdentifiers];
NSMutableArray *lanuages = [[NSMutableArray alloc]init];
for (int i = 0; i < [localIdentifiers count]; i++) {
[lanuages addObject:[[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:[localIdentifiers objectAtIndex:i]]];
}
NSLog(#"%#", lanuages);
Try this or You can use another method
NSArray* languages = [[NSUserDefaults standardUserDefaults] objectForKey:#"AppleLanguages"];
for (int i = 0; i < [languages count]; i++) {
NSLog(#"%#", [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:[languages objectAtIndex:i]]);
}

In iOS I have change the language but it shows only text not images

if ([objGlobalUser.strAppLangID isEqualToString:[#"en" uppercaseString]]) {
objGlobalUser.strLanguage =#"en";
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:objGlobalUser.strLanguage, nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"preferredLang: %#", objGlobalUser.strLanguage);
} else {
objGlobalUser.strLanguage =#"ar";
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:objGlobalUser.strLanguage, nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
NSString *path= [[ NSBundle mainBundle ] pathForResource:objGlobalUser.strLanguage ofType:#"lproj" ];
self.viewController = [[MyViewController alloc] initWithNibName:#"MyViewController"
bundle:[NSBundle bundleWithPath:path]];
It only shows strings not images when language change
As for me, I've done all manipulations with localization in main.m and it works fine.
Here's an example:
//Localization Language setup
typedef enum {
LLAuto = 0,
LLEnglish = 1,
LLFrench = 2,
LLJapanese = 3,
LLSpanish = 4
} TLocalizationLanguage;
static NSString * const LocalizationLanguages[] = {
#"auto", #"en", #"fr", #"ja", #"es"
};
void setupLocalizationLanguage() {
TLocalizationLanguage UsedLng = (TLocalizationLanguage) USE_LOCALIZATION_LANGUAGE;
if (UsedLng == LLAuto) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"AppleLanguages"];
} else {
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:LocalizationLanguages[UsedLng], nil] forKey:#"AppleLanguages"];
}
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"Use localization language: %#", LocalizationLanguages[UsedLng]);
}
// -------------------------------------------------------------------------------
#import "AppDelegate.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
setupLocalizationLanguage();
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
where USE_LOCALIZATION_LANGUAGE is an environment variable.
I hope it will be useful to you.

Resources