Can someone help with a method of how to launch into a view that an might have quit in or suspended in. E.g.
I launch the app.
Go Open a couple of views within the a and end up in View 4.
Quite the app or go into background mode.
I have read that NSUserDefaults can be used but I am just not sure how.
You can save the view in the userdefaults with:
NSString *valueToSave = #"view4";
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:#"lastView"];
[[NSUserDefaults standardUserDefaults] synchronize];
And then you can load the last view from the userdefaults when the user starts your app again (e.g. in the ViewDidLoad in your startView).
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:#"lastView"];
After that you navigate to the view depending on the savedValue.
Keep in mind that you don't really save a view or something. You just save a short string or value that allows you to know which view you want to load again.
Update in Swift:
To save the last view:
let valueToSave = "view4"
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setValue(valueToSave, forKey: "lastView")
userDefaults.synchronize()
And after the restart of the app:
if let loadedView = userDefaults.valueForKey("lastView") {
// load your view
}
else {
// no last view saved
}
Related
I am basically making a simple notes application. In myViewController I have a UITextView. I want the text that the user types in the UITextView to be saved so that the next time the user opens the app it is still there. How would I go about doing that? I want it to save onto the device so they can type and save a large amount of text.
You could save it easily using NSUserDefaults too.
Add this line of code in your button save event or can add it in your UITextViewDelegate method textViewDidEndEditing: But don't forget to assign delegate of textview using
textView.delegate = self;
Now to store use following code:
NSString *valueToSave = textView.text;
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:#"preferenceName"];
[[NSUserDefaults standardUserDefaults] synchronize];
And to retrieve it back later, use this in your viewDidLoad: or viewWillAppear:
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:#"preferenceName"];
textView.text = savedValue;
Hope it helps.. :)
There are several mechanisms available from iOS for storing data. Which one makes sense for you depends on the size and type of data you want to store and how you need to be able to use it.
A simple place to start might be NSString's writeToFile: (and also Where You Should Put Your App’s Files).
For instance, I want a logon screen in ViewController1 to be displayed if the app is launched for the first time. If the app is not launched for the first time or the user has already logged in, it will just start from ViewController2. How do I implement this?
Try this link: Check for first launch of my application
The best code for this link was done by Omar, in my opinion. But there are a few great answers on there, as well as one answer with good philosophy on the matter. If you want a small explanation on how to run the code and understand it yourself, NSGod has a good code snippet for you.
If that doesn't help, try this link: How to setup first time launch of an iOS App
ALSO, Here's some code I whipped up for you . . .
- (BOOL)isFirstTimeLaunching {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if([defaults integerForKey:#"hasRun"] == 0) {
// Do some first-launch code...
[defaults setInteger:1 forKey:#"hasRun"];
[defaults synchronize];
return YES;
}
return NO;
}
Remember, returning 0 is returning true. Returning anything other than 0 is returning false. When the app hasn't been run yet, the key #"hasRun" will be false, and will return 0. Once it's been run, reset it back to 0 to prevent the first-launch code from running again.
I would use NSUserDefaults. In the AppDelegate.m do something like:
if(![[NSUserDefaults standardDefaults] objectForKey:#"shouldLaunchSignUp"]){
//launch your sign up view controller here
//set the user default to yes
[[NSUserDefaults standardDefaults] setBool:YES forKey:#"shouldLanuchSignUp"];
}
check in viewDidLoad and set a boolean flag.
- (BOOL)isFirstTimeLaunching {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if([defaults integerForKey:#"hasRun"] == 0) {
// Do some first-launch code...
[defaults setInteger:1 forKey:#"hasRun"];
[defaults synchronize];
return YES;
}
return NO;
}
And in viewDidAppear, on basis of flag present your log in view.
Remember , in viewDidLoad you can't present another view.
I want to show a help overlay when a user runs my application for the first time.
To do this, I'm using the following code indidFinishLaunching:
if(![[[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys] containsObject:#"IPHONEFIRSTRUN"])
[[NSUserDefaults standardUserDefaults]setBool:TRUE forKey:#"IPHONEFIRSTRUN"];
In the view controller, I have:
if ([[NSUserDefaults standardUserDefaults]boolForKey:#"IPHONEFIRSTRUN"]==TRUE) {
[self HelpOverlayIphone];
[[NSUserDefaults standardUserDefaults]setBool:FALSE forKey:#"IPHONEFIRSTRUN"];
}
However, it shows the overlay on the second use as well. How can I fix this? Any help is appreciated.
Your logic is overly complex. You are setting permanently a user default to indicate something happening one time. Instead, in the view controller see if the value is not set, if it is do your action and set the variable so that the code is NOT run again:
if ( ! [[NSUserDefaults standardUserDefaults]boolForKey:#"IPHONEFIRSTRUNCOMPLETE"] ) {
[self HelpOverlayIphone];
[[NSUserDefaults standardUserDefaults]setBool:YES forKey:#"IPHONEFIRSTRUNCOMPLETE"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Take out all the code in the app delegate.
Also it's very likely your original code is not working because you are stopping the app from XCode. If you don't use synchronize user default changes will not be saved in that case (normal quitting of the app does eventually save the changes permanently).
Have you registered the defaults you are using at the start of the program? I would suggest rereading the apple documentation for NSUserDefaults here
You need to first make a call to
- (void)registerDefaults:(NSDictionary *)dictionary
which will only set the key if it doesn't already exist. Then check the key for falseness on the the first run and set it at this point.
My guess is the reason your code isn't working is because the dictionary is never actually being saved in any sort of persistent way.
I have this function which fires when the app fires up- it's always been reliable. I have a uniqueNameOfApp which is just some random hash so that it doesn't collide with other apps.
-(void)loadSettings {
NSMutableDictionary *sttngs = [[NSUserDefaults standardUserDefaults]
objectForKey:uniqueNameOfApp];
if(sttngs != nil) {
[userSettings addEntriesFromDictionary:sttngs];
} else {
_appFiredForFirstTime = YES;
}
}
I am using NSUSerDefaults to store a couple strings and integers for my application. Whenever a view is opened, the string is loaded slower than the view so you see a glitch. For example, I save the selectedSegmentIndex and then read it in viewDidAppear and for a quick moment when the view is called, no segment is selected, then the right one selects. How do you make it so there is no time gap between the view being opened and the setting be read?
- (void)viewDidLoad
{
[super viewDidLoad];
int segmentIndex = [[NSUserDefaults standardUserDefaults] integerForKey:#"selectedIndex"];
unitSegmentControl.selectedSegmentIndex = segmentIndex;
BOOL location = [[NSUserDefaults standardUserDefaults] boolForKey:#"locationManager"];
[gpsSwitch setOn:location animated:NO];
deviceID.text = [[NSUserDefaults standardUserDefaults] stringForKey:#"DeviceID"];
}
- (IBAction)changeSeg:(id)sender {
if (unitSegmentControl.selectedSegmentIndex == 0) {
[[NSUserDefaults standardUserDefaults] setObject:#"http://98.246.50.81/firecom/xml/units/E01.xml" forKey:#"parserURL"];
[[NSUserDefaults standardUserDefaults] setObject:#"Hillsboro Main" forKey:#"selectedStation"];
[[NSUserDefaults standardUserDefaults] setObject:#"Hillsboro Fire & Rescue" forKey:#"selectedDepartment"];
}
if (unitSegmentControl.selectedSegmentIndex == 1) {
[[NSUserDefaults standardUserDefaults] setObject:#"http://98.246.50.81/firecom/xml/units/E02.xml" forKey:#"parserURL"];
[[NSUserDefaults standardUserDefaults] setObject:#"Hillsboro Witch Hazel" forKey:#"selectedStation"];
[[NSUserDefaults standardUserDefaults] setObject:#"Hillsboro Fire & Rescue" forKey:#"selectedDepartment"];
}
[[NSUserDefaults standardUserDefaults] setInteger:unitSegmentControl.selectedSegmentIndex forKey:#"selectedIndex"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
The defaults are not slow, you’re just loading the data too late. The standard place to populate views is in -viewDidLoad or -viewWillAppear in the view’s controller. Both will update the view soon enough to avoid visual glitches. If any of the two doesn’t work for you, here’s some tips to find the reason:
Try to set the selected index to a hard-wired number. This will tell you if the problem is in the defaults or (much more likely) in the -setSelectedSegmentIndex call.
Move the UI population code to -viewWillAppear. That’s the latest moment to update the UI before it’s displayed.
Use NSParameterAssert to make sure unitSegmentControl is not nil.
Make sure the index read back from the defaults is the expected number. Generally, it’s best to pull the defaults keys into constants. That way you can’t bump into simple typo bugs:
static NSString *const SelectedSegmentKey = #"selectedSegment";
If everything else fails, use a custom UISegmentControl subclass for your unitSegmentControl and place a breakpoint into -setSelectedSegmentIndex to see who else might be calling it.
I have a scroll view full of buttons which are also in an NSMutableArray
how can i save the scrollview with the buttons so that they load in view did load.
I have a function that loads the buttons and places them into the scroll view and i have a function that removes the buttons. So it's the end state of the scrollview and its buttons needing to be saved.
If I can just save the array thats ok because I have a createButton function which takes in an NSString and creates a button in the scrollview and adds the object to the array so i suppose i could have 2 arrays but that hasn't worked and I'm fairly new so I think there is probably some really nice way to do this.
Thanks in advance!
Using NSUserDefaults, this is how you would do it. This is how you would save just one array:
[[NSUserDefaults standardUserDefaults] setObject:yourArray forKey:#"SavedArray"];
And then load it:
yourArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"SavedArray"];
Or you could save button locations and button titles separately:
To save...
[[NSUserDefaults standardUserDefaults] setObject:titlesArray forKey:#"Titles"];
[[NSUserDefaults standardUserDefaults] setObject:locationsArray forKey:#"Locations"];
And to load...
titlesArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"Titles"];
locationsArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"Locations"];
NSUserDefaults are actually very cool how simple they are. I hope this has helped.