used NSString object in another file shown always null value ? - iphone

i have two .m file .i used nsstring object on another .m file its always null.
//postputgetFunction.h
#property(retain,nonatomic) IBOutlet NSMutableString *postRegisterResponseUserId;
//postputgetFunction.m
#synthesize postRegisterResponseUserId;
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if ([flag isEqualToString:#"post"])
{
NSLog(#"Post received data here.....");
NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
postRegisterResponseName=[dict valueForKey:#"Name"];
postRegisterResponseSuccess=[dict valueForKey:#"Success"];
postRegisterResponseUserId=[dict valueForKey:#"UserId"];
NSLog(#"ReceiveData :Name : %# \n Success : %# \n UserId : %#",postRegisterResponseName,postRegisterResponseSuccess,postRegisterResponseUserId);
//Above statement display the value properly..........
flag=Nil;
}
}
but i am using in another .m file ... In this .m file its shown null value .. like this,
//Verification.h
#import "PostPutGetFunction.h"
#property (retain, nonatomic) PostPutGetFunction *postputgetFunction;
//verification.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
postputgetFunction=[[PostPutGetFunction alloc]init];
}
- (IBAction)verificationBtnClick:(id)sender
{
NSLog(#"%#",postputgetFunction.postRegisterResponseUserId);
//here its always shown NULL ... i didnt get the value here ...
}

In other .m file's viewDidLoad method you allocating and initializing the PostPutGetFunction using
postputgetFunction=[[PostPutGetFunction alloc]init];
That's why the variable defined in PostPutGetFunction class NSMutableString *postRegisterResponseUserId initialized to Null. You can use the Delegates for passing the data between the two controllers. Or alternatively you can store the userID in NSUserDefault class like below
**First Part**
NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSString *name =[dict valueForKey:#"Name"];
NSString *success=[dict valueForKey:#"Success"];
NSString *userid =[dict valueForKey:#"UserId"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:name forKey:#"NAME"];
[defaults setObject:success forKey:#"SUCCESS"];
[defaults setObject:userid forKey:#"USERID"];
[defaults synchronize];
And to retrieve the values in another class.m use below code
**Second Part**
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *name = [defaults objectForKey:#"NAME"];
NSString *success = [defaults objectForKey:#"SUCCESS"];
NSString *userid = [defaults objectForKey:#"USERID"];
And also you do not use IBOutlet for NSMutableString type rather it's used for UI Control types like Below

You are Declaring a new object of PostPutGetFunction, and for sure the value postRegisterResponseUserId will be null
if you want to accomplish that you have to use Delegation, take a look at this answer

Related

Storing custom OrderedDictionary to NSUserDefaults

I need to save the OrderedDictionary to NSUserDefaults.
I read here and in many other posts how to do it:
-(id)initWithCoder:(NSCoder *)decoder{
if (self != nil){
dictionary = [decoder decodeObjectForKey:#"dictionary"];
array = [decoder decodeObjectForKey:#"array"];
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)encoder{
[encoder encodeObject: dictionary forKey:#"dictionary"];
[encoder encodeObject: array forKey:#"array"];
}
I then call it like this:
OrderedDictionary *od = [OrderedDictionary dictionaryWithDictionary:[businessInfo objectForKey:#"allowedStates"]];
NSData *archivedObject = [NSKeyedArchiver archivedDataWithRootObject:od];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:archivedObject forKey:#"allowedStates"];
[defaults synchronize];
and unarchive it like this:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *archivedObject = [defaults objectForKey:#"allowedStates"];
OrderedDictionary *countryStates = (OrderedDictionary *)[NSKeyedUnarchiver unarchiveObjectWithData:archivedObject];
I see that archivedObject is not empty, however countryStates is empty, although when I save it it's not empty.
How is it?
How can I archive successfully the OrderedDictionary?
EDITED
The method initWithCoder is being called, but not encodeWithCoder
Please refer below link, may be will you get proper solution.
encodeWithCoder is not called in derived class of the NSMutableDictionary
When does encodeWithCoder get called?
Good Luck !!!!
Make sure your class conforms to the <NSCoding> protocoll (so your class definition reads #interface OrderedDictionary <NSCoding>)
Else, the framework doesn't know it should call encodeWithCoder:

How to save User Name and Password in NSUserDefault?

I need to save User Name and Password in NSUserDefault. I am planning to place a round rect button in IB. On pressing of which the User name and Password would be saved in NSUserDefault, so that when user kills the application and tries to login again after some time, they do not need to enter their login details again.
Any help would be highly appreciated.
Thanks and best regards,
PC
For Saving Username and Password I will personally suggest to use Keychain as they are more safer than NSUserDefault in terms of security since Keychain stores data in encrypted form while NSUserDefault stores as plain text. If you still want to use NSUserDefault Here's the way
FOR SAVING
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// saving an NSString
[prefs setObject:txtUsername.text forKey:#"userName"];
[prefs setObject:txtPassword.text forKey:#"password"];
[prefs synchronize];
FOR RETRIEVING
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// getting an NSString
NSString *savedUsername = [prefs stringForKey:#"userName"];
NSString *savedPassword = [prefs stringForKey:#"password"];
Do not store plaintext passwords in user defaults, even if they are unimportant.
Use Keychain Services. The Generic Keychain Sample provides sample KeychainWrapper class, that can be used for reading and writing data into keychain with exactly the same setObject:forKey: interface as NSUserDefaults uses.
To Save:
[[NSUserDefaults standardUserDefaults] setValue:_Username forKey:#"Username"];
[[NSUserDefaults standardUserDefaults] setValue:_password forKey:#"password"];
[[NSUserDefaults standardUserDefaults] synchronize];
To Read:
NSString * _UserName = [[NSUserDefaults standardUserDefaults] stringForKey:#"Username"];
NSString * _password = [[NSUserDefaults standardUserDefaults] stringForKey:#"password"];
First off, I would not store the password in NSUserDefaults. I would rather use the keychain.
This is how you can save the username in NSUserDefaults:
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
[standardUserDefaults setObject:myString forKey:#"username"];
NSString* username = [standardUserDefaults objectForKey:#"username"];
On the other hand, an easy way to use the keychain is by using the SSKeychain class by Sam Soffes; in this case you would just say:
NSString* password = [SSKeychain passwordForService:#"YOUSERVICENAMEHERE" account:username];
[SSKeychain setPassword:password forService:#"YOUSERVICENAMEHERE" account:username];
You can store your credentials like this:
-(void)saveToUserDefaults:(NSString*)stringUserName pswd:(NSString*)strPassword
{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
if (standardUserDefaults) {
[standardUserDefaults setObject:stringUserName forKey:#"UserName"];
[standardUserDefaults setObject:strPassword forKey:#"Password"];
[standardUserDefaults synchronize];
}
}
And you can retrive them like this:
-(NSArray*)retrieveFromUserDefaults
{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
if (standardUserDefaults) {
NSString *userName = (NSString*)[standardUserDefaults objectForKey:#"UserName"];
NSString *password = (NSString*)[standardUserDefaults objectForKey:#"Password"];
}
NSArray* credentials = [NSArray arrayWithObjects:userName, password, nil];
return credentials;
}
Cannot set NSUserDefaults field
Posted my code from link to stay assured that answer is still useful to community even if the above mentioned post is removed or deleted in future.
Code:
You can try this code. I am very sure that it will work for you.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *uid=#"1";
[defaults setObject:uid forKey:#"init_val"];
[defaults synchronize];
For Retrieving Data You Should Use The Following Code :
NSString *initVal=[[NSUserDefaults standardUserDefaults] valueForKey:#"init_val"];
OR
NSString *initVal=[[NSUserDefaults standardUserDefaults] objectForKey:#"init_val"];
EDIT:
If still it gives nil, then you can use the following code:
NSString *initVal=[NSString stringWithFormat:#"%#",[[NSUserDefaults standardUserDefaults] valueForKey:#"init_val"]];
OR
NSString *initVal=[NSString stringWithFormat:#"%#",[[NSUserDefaults standardUserDefaults] objectForKey:#"init_val"]];
In the above link, you will find my answer and replace "init_val" in my code there with your "username" and "password" as keys
Hope this helps you.
Good Answers are already given But here is a clean way of Saving/Loading/Deleting User Credentials in the keychain. Consider this, you can create a separate class and include the following code:
.h
#import <Foundation/Foundation.h>
#interface KeychainUserPass : NSObject
+ (void)save:(NSString *)service data:(id)data;
+ (id)load:(NSString *)service;
+ (void)delete:(NSString *)service;
#end
.m
#import "KeychainUserPass.h"
#implementation KeychainUserPass
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
return [NSMutableDictionary dictionaryWithObjectsAndKeys:
(__bridge id)kSecClassGenericPassword, (__bridge id)kSecClass,
service, (__bridge id)kSecAttrService,
service, (__bridge id)kSecAttrAccount,
(__bridge id)kSecAttrAccessibleAfterFirstUnlock, (__bridge id)kSecAttrAccessible,
nil];
}
+ (void)save:(NSString *)service data:(id)data {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData];
SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL);
}
+ (id)load:(NSString *)service {
id ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
[keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
#try {
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
}
#catch (NSException *e) {
NSLog(#"Unarchive of %# failed: %#", service, e);
}
#finally {}
}
if (keyData) CFRelease(keyData);
return ret;
}
+ (void)delete:(NSString *)service {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
}
#end

Saving ALAsset URL in NSUserDefaults

Hi I have my ALAsset URL save in NSMutableArray,
"ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=119A0D2D-C267-4B69-A200-59890B2B0FE5&ex‌​t=JPG",
"ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=92A7A24F-D54B-496E-B250-542BBE37BE8C&ex‌​t=JPG",
"ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=77AC7205-68E6-4062-B80C-FC288DF96F24&ex‌​t=JPG
I wasnt able to save NSMutableArray in NSUserDefaults due to it having an error Note that dictionaries and arrays in property lists must also contain only property values.
Im thinking of using this :
- (void)encodeWithCoder:(NSCoder *)encoder {
//Encode properties, other class variables, etc
[encoder encodeObject:self.selectedPhotos forKey:#"selectedPhotos"];
}
- (id)initWithCoder:(NSCoder *)decoder {
if((self = [super init])) {
//decode properties, other class vars
self.selectedPhotos = [decoder decodeObjectForKey:#"selectedPhotos"];
}
return self;
}
then save and retrieve it with this code:
- (void)saveCustomObject:(MyCustomObject *)obj {
NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:obj];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myEncodedObject forKey:#"myEncodedObjectKey"];
}
- (MyCustomObject *)loadCustomObjectWithKey:(NSString *)key {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *myEncodedObject = [defaults objectForKey:key];
MyCustomObject *obj = (MyCustomObject *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
return obj;
}
But I somehow dont quite get it, still crashes in my code. Dont know how. And I wasnt able to save it in NSUserDefaults. Hope someone help. Really been having problem with this a while. Hope someone guide me on the right path of saving and retrieving it the right way from NSUserDefaults. Then back to a NSMutableArray.
The NSUserDefaults only takes a restricted set of classes as objects. See the documentation. You must take care only to store values of these types (NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary, and of course it applies recursively) in the dictionary.
To store the URLs in the NSUserDefaults, store them as strings, then read them back as URLs. If you need to have the dictionary in the current format, you may have to transform it before saving it.
- (void) saveMyUrls
{
NSMutableArray* urls = [NSMutableArray arrayWithCapacity:self.myUrls.count];
for(NSURL* url in self.myUrls) {
[urls addObject:[url absoluteString]];
}
[[NSUserDefaults standardUserDefaults] setObject:urls forKey:#"myUrls"];
}
- (void) loadUrls
{
NSArray* urls = [[NSUserDefaults standardUserDefaults] objectForKey:#"myUrls"];
self.myUrls = [NSMutableArray arrayWithCapacity:urls.count];
for(NSString* urlString in urls) {
[self.myUrls addObject:[NSURL URLWithString:urlString]];
}
[[NSUserDefaults standardUserDefaults] setObject:urls forKey:#"myUrls"];
}
If you need to save more information than just the URL, let's say a user-specified label, you could save the object as a NSDictionary instead, e.g.
- (void) saveMyUrlsWithLabels
{
NSMutableArray* objs = [NSMutableArray arrayWithCapacity:self.myObjects.count];
for(MyObject* obj in self.myObjects) {
[objs addObject:[NSDictionary dictionaryWithKeys:#"url", #"label"
forObjects:obj.url.absoluteString, obj.userSpecifiedLabel];
}
[[NSUserDefaults standardUserDefaults] setObject:objs forKey:#"myObjects"];
}
Maybe you should do it like this:
- (MyCustomObject *)loadCustomObjectWithKey:(NSString *)key {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults synchronize]; // note this
NSData *myEncodedObject = [defaults objectForKey:key];
MyCustomObject *obj = nil;
// it would be even better
// to wrap this into #try-#catch block
if(myEncodedObject)
{
obj = (MyCustomObject *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
}
return obj;
}
Also note that if you want to use NSKeyedArchiver and NSKeyedUNarchiver your MyCustomObject class has to conform to NSCoding protocol. Check NSCoding protocol reference and Archives and Serializations Programming Guide.
This is another way to do it and yes you can use NSUserDefaults. Basically you get asset URL, save it and then convert it back to an asset / image
//SET IT
ALAsset *asset3 = [self.assets objectAtIndex:[indexPath row]];
NSMutableString *testStr = [NSMutableString stringWithFormat:#"%#", asset3.defaultRepresentation.url];
//NSLog(#"testStr: %# ...", testStr);
[[NSUserDefaults standardUserDefaults] setObject:testStr forKey:#"userPhotoAsset"];
[[NSUserDefaults standardUserDefaults] synchronize];
//GET IT
NSString *assetUrlStr = [[NSUserDefaults standardUserDefaults] objectForKey:#"userPhotoAsset"];
NSURL* aURL = [NSURL URLWithString:assetUrlStr];
NSLog(#"aURL: %# ...", aURL);
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library assetForURL:aURL resultBlock:^(ALAsset *asset)
{
UIImage *copyOfOriginalImage = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage] scale:1.0 orientation:UIImageOrientationUp];
imgVwPortrait.image = copyOfOriginalImage;
}
failureBlock:^(NSError *error)
{
// error handling
NSLog(#"failure-----");
}];

NSUserDefaults doubts

#pragma mark SA_OAuthTwitterControllerDelegate
- (void) OAuthTwitterController: (SA_OAuthTwitterController *) controller authenticatedWithUsername: (NSString *) username {
NSLog(#"Authenicated for %#", username);
[_btnTwitter setTitle:username forState:UIControlStateNormal];
}
I have this code for displaying username for twitter ,and it works well,but when i navigate to another page and came back the title username of the button disappears,i know we have to set a NSUserDefault value in viewwillapper for checking the username exists or not.But i didn't know how to handle the nSUserDefault,if anyone have an idea to solve this issue please help me.
Thanks in advance.
EDIT:
- (void)viewWillAppear:(BOOL)animated{
//Sets up the NSUserDefaults
//Sets up the NSUserDefaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//Checks if there is a saved User Name
if([defaults objectForKey:#"kTwitterUserName"])
NSString *username = [defaults objectForKey:#"kTwitterUserName"];
[_btnTwitter setTitle:username forState:UIControlStateNormal];
else
{
}
this is how my viewwillappear lokks
and
- (void) OAuthTwitterController: (SA_OAuthTwitterController *) controller authenticatedWithUsername: (NSString *) username {
NSLog(#"Authenicated for %#", username);
[_btnTwitter setTitle:username forState:UIControlStateNormal];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:username forKey:#"kTwitterUserName"];
[defaults synchronize];
}
this is how my twitermethod looks like
NSUserDefaults are very simple to work with. They are kind of like a dictionary, you set an object and a key. So to do what your trying to do, you can use something like the following:
//This just sets up the defaults - similar to allocating a dictionary
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
Then to set an object in your defaults, you set an object/key pair like this:
[defaults setObject:username forKey:#"kTwitterUserName"];
It is important to call this method at some point: [defaults synchronize];. This explicitly saves the defaults. So you might as well do it immediately after you set the username key.
Then to read the saved username:
NSString *username = [defaults objectForKey:#"kTwitterUserName"];
Your oAuth Method should look like this:
- (void) OAuthTwitterController: (SA_OAuthTwitterController *) controller authenticatedWithUsername: (NSString *) username {
//Any thing else you want to do - NSLogs, etc.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:username forKey:#"kTwitterUserName"];
[defaults synchronize];
}
So your viewWillAppear will look something like this:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//Sets up the NSUserDefaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//Checks if there is a saved User Name
if([defaults objectForKey:#"kTwitterUserName"]) {
NSString *username = [defaults objectForKey:#"kTwitterUserName"];
} else
//Do something else because there is no saved username
NSLog(#"no username saved");
}
Let me know in a comment if you need any clarification.
You're correct in the aspect you'll want to save this somehow, and NSUserDefaults will work fine for this. Save and read samples are below:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// saving an NSString
[prefs setObject:#"username" forKey:#"UsersUsername"];
// reading an NSString
NSString *theString = [prefs stringForKey:#"UsersUsername"];
http://www.icodeblog.com/2008/10/03/iphone-programming-tutorial-savingretrieving-data-using-nsuserdefaults/ for more details

How to change iPhone app language during runtime?

Is there a way to change the application language during runtime?
So, after the change NSLocalizedString immediately returns the string for the new language.
What I'm doing now is changing the language using the code below:
- (void)onChangeLanguage: (id)sender
{
NSArray *lang = [NSArray arrayWithObjects:((InfoWhatever *)sender).language, nil];
[[NSUserDefaults standardUserDefaults] setObject:lang forKey:#"AppleLanguages"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *languages = [defaults objectForKey:#"AppleLanguages"];
NSString *currentLanguage = [languages objectAtIndex:0];
NSLog(#"Current language: %#", currentLanguage);
}
The language will change but only after restarting the app.
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
NSMutableArray* languages = [userDefaults objectForKey:#"AppleLanguages"];
[languages insertObject:#"de" atIndex:0]; // ISO639-1
[[NSUserDefaults standardUserDefaults] synchronize];
The trick to use specific language by selecting it from the app is to force the NSLocalizedString to use specific bundle depending on the selected language ,
here is the post i have written for this http://learning-ios.blogspot.com/2011/04/advance-localization-in-ios-apps.html
and here is the code of one sample app https://github.com/object2dot0/Advance-Localization-in-ios-apps
You Can do it . Here is the way
http://aggressive-mediocrity.blogspot.com/2010/03/custom-localization-system-for-your.html
In Brief Download and add 2 files to the project
http://dl.dropbox.com/u/2917666/LocalizationSystem/LocalizationSystem.h
http://dl.dropbox.com/u/2917666/LocalizationSystem/LocalizationSystem.m
2
#import "LocalizationSystem.h"
3
- (IBAction)btnEnglishClicked:(id)sender {
LocalizationSetLanguage(#"en");
}
4 After you set the language as above
AMLocalizedString(#"Key", nil)
Thats it.
I doubt you can do this, even the Settings app cannot do it.
(When you change the language in the Settings app, the screen goes black, and displays "setting language..." and a progress wheel. After a long wait, you are back in Springboard. It almost looks like the phone reboots.)
I came up with a solution that allows you to use NSLocalizedString. I create a category of NSBundle call NSBundle+RunTimeLanguage. The interface is like this.
// 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
The implementation is like this.
// 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
Than just add import NSBundle+RunTimeLanguage.h into the files that use NSLocalizedString.
As you can see I store my languageCode in a property of AppDelegate. This could be stored anywhere you'd like.
This only thing I don't like about it is a Warning that NSLocalizedString marco redefined. Perhaps someone could help me fix this part.
Simply add these lines:
#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:#"lproj"]]
1. NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:#[#"en"] forKey:#"AppleLanguages"]; [defaults
synchronize];
2. _label.text = NSLocalizedStringFromTableInBundle(#"Key", nil, currentLanguageBundle, #"");
try this:
object_setClass([NSBundle mainBundle],[MyBundle class]);
https://github.com/maximbilan/ios_language_manager/blob/master/README.md