Im having a ViewController on which on clicking a button, label gets updated. I want is, each time the app opens it should retain its old value. Im able to write every value in NSUserDefault but not getting how to write the value on label before the app loads.
Example:
In first run the label is having the value 5.
In second run the label should contain the same value 5, and if i made any changes that change should be there in third run.
Thanx...
In your AppDelegate, the very first method gets called after launching an App is,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
return YES;
}
and for other cases such as from inactive to active state of your application use,
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
I recommend Reading, Apple's iOS application lifecycle documentation.
Here's how to retrieve a stored value from NSUserDefaults and set the value for your label when your ViewController loads:
- (void)viewDidLoad
{
[super viewDidLoad];
self.myLabel.text = [[NSUserDefaults standardUserDefaults] objectForKey:#"mySavedValue"];
}
I'm assuming your button is already hooked up to an action something like this that will save the value to the standardUserDefaults when clicked:
- (IBAction)buttonPressed:(id)sender
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:self.myLabel.text forKey:#"mySavedValue"];
[defaults synchronize];
}
Related
I’m new in iOS development. My question is, I’ve two view controllers.
viewController - A viewController - B
Now, if i killed the app from the viewController - A and than relaunch the app. than app must be open the viewController - A. and if i killed the app from the viewController - B and than relaunch the app. than app must be open the viewController - B.
Can anyone help me, I’ve done the RND but can not find the proper solution.
Thanks
Create a sharedDelegate in AppDelegate.m file
+(AppDelegate *)sharedDelegate {
return (AppDelegate *) [UIApplication sharedApplication].delegate;
}
in AppDelegate.h
+ (AppDelegate *)sharedDelegate;
#property (nonatomic, strong) NSString *currentViewContoller;
when push to any contoller then set AppDelegate's currentViewContoller to new VC
YourViewController *vc=[[YourViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
[AppDelegate sharedDelegate].currentViewContoller = NSStringFromClass([YourViewController class]);
now when app is terminated
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
[[NSUserDefaults standardUserDefaults]setObject:[AppDelegate sharedDelegate].currentViewContoller forKey:#"currentVC"];
}
now when app launched first time check previous controller when app terminated
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSString *string=[[NSUserDefaults standardUserDefaults] valueForKey:#"currentVC"];
and push this class
UIViewController *object = [[NSClassFromString(string) alloc] init...];
}
applicationWillTerminate you can use but it will only get called if user quit app from forground If your app is in background and then user quit app then applicationWillTerminate will not get called.
So, you have to take care of applicationDidEnterBackground.
So, when app enter in background (i.e call applicationDidEnterBackground ) or call applicationWillTerminate save state(your current VC) in your user defaults.
Now in your didFinishLaunchingWithOptions set that view controller as rootviewcontroller or whatever way that you want to manage it.
reference : Apple documentation for applicationWillTerminate
PS : You should not manage app like this. It is horrible way!! If possible then run your app as normal flow!
If you're using Storyboards you can use the Restoration Identifier to communicate the App which controller to launch as first
https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/PreservingandRestoringState.html
I want to do something like this in my iOS app. Let's say user open the app now. then I want to show a view. during that 1st hour, no matter how manytimes he open the app I need to show the 1st view through out this hour. when start a new hour I want to show the view 2. again after the 3rd hour I need to show that first view.
Like wise
1hr - view 1
2hr - view 2
3hr - view 1
4hr - view 2
How can I monitor this hours changing from my ios app even its not runing in the background
Thank you
If the app isn't running in the background, you really can't monitor the hour changing. But that doesn't matter since you can't show a view when the app is not running.
When the app is running, just use NSTimer and set it to repeat at the right time to tell your controller that the hour is changing. Let the controller deal with figuring out which view to show.
This is important, because you have to make the decision of which view to show even when the hour isn't changing. For example, when you first open the app.
See NSTimer
AppDelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
[standardDefaults setObject:[NSDate date] forKey:#"kTimeInterval"];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationNameForBecameActive object:nil userInfo:#{kUserInfoForBecameActive: self.currentTime}];
}
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didBecomeActive:) name:kNotificationNameForBecameActive object:nil];
}
- (void)didBecomeActive:(NSNotification *)notification {
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
NSDate *previousDate = [standardDefaults objectForKey:#"kTimeInterval"];
NSTimeInterval secondsPassed = [[NSDate date] timeIntervalSinceDate:previousDate];
if (secondsPassed >= CHECK_SWAP_VIEW) {
// Change your view here.
}
}
Here you can do like save time when application goes in background or quit. Then whenever application will open check for previous time and then swap your views.
I have registered my app to be able to open HTML files. I would like the app to keep the last HTML file it opened... If I open a new HTML file, I would like it to overwrite the last one opened.
I have attempted to user the Documents directory and its not working for me. I have also tried using NSUserDefaultsto no avail. Here is what i currently have:
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
ViewController *vc = (ViewController *)self.window.rootViewController;
[vc loadFileWithUrl:url];
[[NSUserDefaults standardUserDefaults] setURL:[url fileReferenceURL] forKey:#"amd"];
return YES;
}
I kill the application entirely, then - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions is called. Here is how that method looks:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *url = [[NSUserDefaults standardUserDefaults] URLForKey:#"amd"];
if (url)
{
ViewController *vc = (ViewController *)self.window.rootViewController;
[vc loadFileWithUrl:url];
}
return YES;
}
url is always nil :(
PS: I have also tried storing the HTML file in its string representation, and I am able to get that to persist in the Documents folder, but when I try to load that string using:
[webView loadHTMLString:htmlString]; the page never loads. I think that has something to do with the Javascript but I'm not too sure.
The user defaults are saved when the app goes to the background, or when you call -synchronize on the user defaults. When developing, you often don't put the app into background, but just kill it through XCode, in which case nothing gets saved. You can save the user defaults by pressing the home button on your iPhone/iPad, and killing the app in XCode 1second later.
Also, you should put a log statement into your first method, like NSLog(#"saving amd to %#", [url fileReferenceURL]); to be sure that it really gets saved!
It seems that you forgot to call
[[NSUserDefaults standardUserDefaults] synchronize];
Docs:
Writes any modifications to the persistent domains to disk and updates
all unmodified persistent domains to what is on disk.
I have a Root.plist file which is used for my app's settings. It has a toggle switch with an identifier of reset_achievements_preference. In the applicationDidBecomeActive method, I have this code:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSLog(#"reset achievements: %i", [[NSUserDefaults standardUserDefaults] boolForKey:#"reset_achievements_preference"]);
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"reset_achievements_preference"]) {
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"reset_achievements_preference"];
[[NSUserDefaults standardUserDefaults] synchronize];
//Code to react to this change
}
}
Sometimes it hits the NSLog and notices the object change, but sometimes it doesn't. I wonder if I'm dealing with this incorrectly?
Try adding:
[[NSUserDefaults standardUserDefaults] synchronize]
To applicationDidBecomeActive: before anything else to refresh the status of the user defaults. Thy synchronize method is called periodically by the application, but you can refresh it manually.
When do you want to handle your reset_achievements_preference option? The method applicationDidBecomeActive is called when the application starts and when the application returns from background (is brought to foreground by the user).
If you want to handle reset_achievements_preference only at application startup, it is possible that the user puts your app into background, then returns to it. In this case applicationDidBecomeActive is called and it sets reset_achievements_preference to NO which probably is not what you want.
You can simply move this code to application:didFinishLaunchingWithOptions: method to solve this problem.
So, here is my life story that I can't seem to figure out what's wrong!!!
I have an app that's already in the store and it has a weird issue which it gives out mixed results.
I have two switches in my main view both controls local notification with repeat intervals.
now I've set up the switches right and ready to go. (I guess).
However, when repeat intervals are scheduled they have to be cancelled again when the user decided not to receive notifications. So, I had my switches coded like that:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
BOOL switchOn = [userDefaults boolForKey:#"switchO"];
if (switchOn) {
[self Firstnotif];
[self Secondnotif];
[self Thirdnotif];
[self Lastnotif];
}
else { [[UIApplication sharedApplication] cancelAllLocalNotifications]; }
BOOL switchOn2 = [userDefaults boolForKey:#"switchO2"];
if (switchOn2) {
[self Firstnotif];
}
else { [[UIApplication sharedApplication] cancelAllLocalNotifications]; }
}
notice I have used the method Firstnotif twice in both switches.
My issues are:
I used to have only one switch and when they turn the first switch on to receive these four notification, doesn't work with all of the users. so I tell them to switch it off, press home button, open app again switch it on and home button again. It works!!!! why?
Now, since I've added another switch new mixed results are appearing.
the second switch is to only fire first notification with it's repeat interval. Some say it works, some say not. others say when I turn the other one it does and does not. What are they facing here??
My questions,
Am I canceling the repeat intervals in the right way?
What could be wrong with my app? and I'll provide you with more codes if needed.
I appreciate your inputs as I've spent weeks on these issues with no luck.
I solved it!
I replaced the cancellation request under applicationDidBecomeActive method and removed my else
guess what? It worked!!! :)