Relaunch app after changing the language in Objective-C - ios

I am changing the language using
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"fr", #"en", nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
when user taps on a button.But the user must restart the app in order for language to change.
Is there anyway possible to restart or relaunch the app when user taps the button?

Yes. There is a possibility, you can do it as Instagram iOS app. In that after changing the language in setting, they will show an alert to restart. When pressed they will force quit the app.
Note: Please check with apple guidelines before implementing it.

You can go to the main storyboard after changing the language.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateInitialViewController];
[UIApplication sharedApplication].delegate.window.rootViewController = vc;

Related

Show a view just once in whole life cycle of an App

I am working on a shopping app and on app launch, it shows signup view and once skip button is clicked it navigates to home view. I want to show signup view just once in whole life time of an app.
Adding here the code I used to show walkthrough screen only once in the entire application lifecycle. This can be useful to you.
// show walkthough for first time only (first time the app launches after download).
bool shownFlag = [[NSUserDefaults standardUserDefaults] boolForKey:#"walkthroughShownOnce"];
if(!shownFlag){
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:#"walkthroughShownOnce"];
[[NSUserDefaults standardUserDefaults] synchronize];
WalkThroughViewController *vc=[[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"WalkThroughViewController"];
[self.window makeKeyAndVisible];
[self.window setRootViewController:vc];
}else{
//if not walkthough go and check other task
}

Switching between storyboard localization

I have application using storyboard with two language (Ar/En) how i can switch from Arabic storyboard to English storyboard without need to change language iPhone settings (At run time).
When user change manually the language, i use :
+ (void)setDefaultLocalizationLanguage:(NSString *)language{
[UserPreferences setDefaultLanguage:language];
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:language, nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
In AppDelegate, I add method switchTolanguage:
-(void)switchTolanguage:(NSString *)lang{
NSBundle *bnd = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:lang ofType:#"lproj" ]];
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Main" bundle:bnd];
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
self.window.rootViewController = initViewController;
}
I execute the last method in my ViewController :
AppDelegate *appdelagate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appdelagate switchTolanguage:[UserPreferences defaultLanguage]];
But I have the same storyboard localization with this logs:
Could not load the "4_icon_4.png" image referenced from a nib in the bundle with identifier "(null)"
Could not load the "1_logo.png" image referenced from a nib in the bundle with identifier "(null)"
Could not load the "1_bacground_img.png" image referenced from a nib in the bundle with identifier "(null)"
But when I kill application and I open it, I have the good storyboard.

Change Initial View Controller for First Launch

I know this question has been asked but the methods are not working for me. I have a view controller that contains a tutorial, which I only want to display as the initial view the first time the app is opened. After that, the main menu will always be the initial view. The storyboard ID for my Tutorial screen is "Tutorial". I have the following code to detect first launch, but I can't figure out how to make the tutorial appear:
- (void)viewDidLoad
{
if ([[NSUserDefaults standardUserDefaults]boolForKey: #"FirstLaunch"])
{}
else{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"FirstLaunch"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
You can change initial controller in two ways:
Check 'Is Initial VC' checkbox at Interface Builder or
Configure it at -application:didFinishLaunchingWithOptions: method
Changing initial view controller using Application Delegate
In -application:didFinishLaunchingWithOptions: in your application delegate (AppDelegate.m) add if/else to check the necessity of tutorial:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
if (![[NSUserDefaults standardUserDefaults] boolForKey: #"FirstLaunch"])
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"FirstLaunch"];
[[NSUserDefaults standardUserDefaults] synchronize];
/*** load vc ***/
}
return YES;
}
To set the initial controller you have to initialize window property, create vc and set it as root:
// 1. Initialize window
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
// 2. Get storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
// 3. Create vc
TutorialViewController *tutorialViewController = [storyboard instantiateViewControllerWithIdentifier:NSStringFromClass([TutorialViewController class])];
// 4. Set as root
self.window.rootViewController = tutorialViewController;
// 5. Call to show views
[self.window makeKeyAndVisible];
Hope it helps!

Programmatically setup/activate Segue

I'm trying to setup a first-launch view in my iOS application. To do this I have the following code to allow me to execute code when the application launches for the first time.
What I want, is when the application launches for the first time, the user is sent to the FirstLaunch view that I've setup in Storyboards, instead of the FirstView view. Every consecutive launch will send the user to the FirstLaunch view.
Currently, I have this code executing in the NavigationController.m, but if this would be better executed in the AppDelegate.m I can change it.
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"FirstLaunch"])
{
// not first launch
}
else
{
// first launch
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"FirstLaunch"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
My question is: How do I setup a segue programably (or activate a segue) to send the user to the FirstLaunch view instead of the normal FirstView?
You do not need a segue for that - all you need is a way to pick the initial view controller programmatically, based on whether or not it's the first launch.
To do that, uncheck the "is initial view controller" in the storyboard on your FirstView, and change your app delegate as follows:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
// Use the name of your storyboard below
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil];
NSString *initialId;
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"FirstLaunch"]) {
// not first launch
initialId = #"FirstViewController";
} else {
// first launch
initialId = #"FirstLaunchViewController";
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"FirstLaunch"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
self.window.rootViewController = [storyboard instantiateViewControllerWithIdentifier:initialId];
[self.window makeKeyAndVisible];
return YES;
}
The code above embeds your code that decides if this is a first launch or not, and sets the storyboard identifier of the target screen based on this decision.
Note that this implementation will never show the user the first launch screen again, even if he didn't get a chance to take a good look the first time that it showed up (e.g. because someone called him, or the device ran out of battery power). A better approach is to read the NSUserDefaults in the same way that you do, but to set it to YES only when the first launch controller is dismissed by the user. This way you would be certain that the user has had enough time to see the screen and interact with it.
In your storyboard set up identifier for segue you need (select segue and choose Attributes Inspector).
After that you can call that segue programmatically:
[self performSegueWithIdentifier:#"indentifier" sender:nil];
This well explained article on segue will answer your question
http://www.appcoda.com/storyboards-ios-tutorial-pass-data-between-view-controller-with-segue/
Sample block of activating and passing data with segue :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController = segue.destinationViewController;
destViewController.recipeName = [recipes objectAtIndex:indexPath.row];
}
}
The Creating a segue programmatically and View Controller Programming Guide for iOS would be good references.

How to create a modal view , for application launch in iOS?

How could i create a modal view , maybe from the delegate to check if its the first time the application launches and show a modal view with a dismiss button , in order to inform the user about something important?
I need the view to show ONLY the first time the application is launched and never again.
Firstly: Check out an earlier answer of mine here: https://stackoverflow.com/a/13563490/1359306
This is for a password protection modal view which I use every time the app is opened. The answer should help a few issues that may arise when implementing your solution. It uses performSegueWithIdentifier as I am using storyboards, but you could also use presentViewController:animated:completion: to present you view.
Then: Note that there is an if statement in place which you can use check if you need to present the view or not. In my case I check to see if the user has been out of the app for more than 5 minutes. I do this by setting a date in NSUserDefaults each time applicationWillResignActive is called - and checking the difference between that and the current date/time).
In your case you could do something like the following:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"firsttime"] == nil) {
//display modal view
[defaults setObject:#"YES" forKey:#"firsttime"];
[defaults synchronize];
}
This checks the NSUserDefaults of the app. If 'firsttime' is nil (which it will be when app is first downloaded) we will show the view. We then set the key to "YES" which means it will never equal nil again - so the view will never show.
This is useful for showing instructions when the app first loads. Alternatively, you could store dates or numbers to make the code more adaptable in the future.
The docs for NSUserDefaults can be found here.
You can achive this using NSUserDefaults.
In delegate.h file
NSString * firstTime;
In .m file
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *myStr = [defaults objectForKey:#"str"];
firstTime =myStr;
if (firstTime.length==0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"hi" message:#"You have open this app first time" delegate:self cancelButtonTitle:#"ok" otherButtonTitles: nil];
[alert show];
[self firstTime];
}
return YES;
}
-(void)firstTime
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *myStr = #"first";
[defaults setObject:myStr forKey:#"str"];
[defaults synchronize];
}
in your AppDelegate using method didFinishLaunchingWithOptions check if your application is launching first time or 2nd time like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"firstTime"])
{
// show your main view controller
}
else
{ // your app is launching first time ....
// show your modalview controller here and dismiss it & go to main view controller
// don't forget to update the key so that next time user don't hang in else statement...
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"firstTime"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
You can use the presentViewController:animated:completion: in the UIViewController class.
So here is what I'd do:
Load your main view controller
Check your user preferences to see if your "firsttime" key exists (in your view did load most likely)
If it doesn't display your one-time view
When it completes (which you can know by having a delegate call back to your main view controller), save the "firsttime" key to your user preferences
no source, code (my Mac is at home), but if you follow these simple steps it should work fine for you.

Resources