This question already has answers here:
Passing data between view controllers
(45 answers)
Closed 5 years ago.
I know this is a frequently asked question and probably the most debated one on Stackoverflow overall. However I have now been searching for the answer for about one week without any luck.
Here is what I want to do..
I have two ViewControllers lets call them mainVC and settingsVC.
In my settingsVC I have a function where the user can put their hourly salary in a textfield that then saves using UserDefaults. This is the data I want to access in the mainVC.
However they don't have any connection to each other (their not bind by any segue and I don't want them to be) and I don't want the mainVC to be instantiated when I save my data.
Furthermore I do not want to use global variables. So what is the best way to do this?
To conclude I simply want to retrieve the data from my settingsVC in my mainVC without using global variables and segues.
You should Use Instance variables , Protocols or Notification for passing data between viewContoller.
Why wouldn‘t you retreive the data from the user defaults? That‘s where the data is stored and is universally available.
You are saving your data in NSUserDefaults. So you have no chance to worry for saving and retrieving data.
To save value
NSString *valueIWantToSet = #"valueToSave"
[[NSUserDefaults standardUserDefaults] valueIWantToSet forKey:#"saveKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
To get this value
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:#"saveKey"];
In case of not saving values in NSUserDefaults, you have to use Notification
Related
This question already has answers here:
How to save local data in a Swift app?
(12 answers)
Closed 6 years ago.
I have a simple swift app that pulls JSON information from online and uses it in a table view. For example, a document would have a name, description, etc. As well as an url to display the pdf. I know how to open the PDF from both local storage and an online url, but if I had an "available offline" value that could be either true or false, where would I store it?
I cannot put it as a JSON key because then it would change the setting for all users accessing the online JSON files, so where do I put a simple device specific option such as this?
NsUserDefault is the best choice for you.
You have to store single variable so.
Coredata is used to small tiny database like if you want to store your data like name , description than you can use coreData.
Here you simple store with NSUserDefaults
Edited:-
To store:-
let value = NSUserDefaults.standardUserDefaults()
value.setInteger (10,forKey: "value")
// here you can use setBool setDouble etc.
To retrieve:-
let num = value.objectForKey ("value") as? Integer
NSUserDefaults is great for easy tiny-scale storage, like remembering settings.
It works like this:
[[NSUserDefaults standardUserDefaults] setObject:#"object" forKey:#"this is my key"];
Then, later,
[[NSUserDefaults standardUserDefaults] objectForKey:#"this is my key"];
//this gives you your object
You just have to be careful with typing, otherwise your app will crash.
Here's the docs for NSUserDefaults:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/
I have a singleton object with the an NSNumber property called recordingNumber that I use to keep track of recordings I have within my app. When the app is first opened, recordingNumber is set to zero and is incremented every time a new recording is saved to the app. When I close my app down and then reopen, the number goes back to zero and every new recording overwrites an old recording. How can I keep the property from going to nil when the app is open and closed? I'm using core data to store all my recording files - should I create a separate entity to store this one value?
#property (nonatomic) NSNumber * recordingNumber;
To persist small amount of data between app instances, data can be stored in NSUserDefaults:
To persist data:
[[NSUserDefaults standardUserDefaults] setObject:self.recordingNumber forKey:#"recordingNumber"]
[[NSUserDefaults standardUserDefaults] synchronize];
In app launch, read this back from NSUserDefaults
self.recordingNumber = [[NSUserDefaults standardUserDefaults] objectForKey:#"recordingNumber"]
There are a number of ways to do this, the easiest is to create a plist that can contain the number and other app settings. The plist is read or created with defaults when the app is opened, and the values are saved each time you update or when you close the app.
You can also create a separate table in your core data to contain the number but it will be overkill unless your table structure actually needs a table to contain historical summaries like MTD (month to date) and YTD totals.
I can't figure out how to make the create an account function work in my application... I have my login system set up like so: http://imgur.com/dKGRnok The first set of strings are the passwords. The second set are the usernames. For someone to create an account that allows them to login, I have to make a string manually through the application. How can I make this function so it gets their input and places it as a string as long as the same username doesn't already exist? http://imgur.com/lVzAV8i
You need to create a local database, the proper way would be to use either sqllite or core data to create your structure, then simply add/remove users.
For an sql tutorial for ios follow this:
http://www.raywenderlich.com/913/sqlite-tutorial-for-ios-making-our-app
Or go to this site and check the section that says "Saving and Loading Data"
http://www.raywenderlich.com/tutorials
I personally prefer core data because its the most complete solution once you get used to setting it up.
If what you are asking is a persistent data, [[NSUserDefaults standardUserDefaults] setValue: forKey:] will be the answer.
Once you save a data with NSUserDefaults, the data will be persistent. You can get the value with [[NSUserDefaults standardUserDefaults] valueForKey:]
Added
I misunderstood your question. In this case you should use local database as Chiques said.
Core Data will be the answer.
http://www.raywenderlich.com/934/core-data-tutorial-for-ios-getting-started
Is it ok to read a value stored in NSUserDefaults from multiple views or you only read it once and then you use another method to pass the data to different part of your app?
In other words I want to know if I’m doing it right, what I’m currently doing in an app I’m working on is basically saving a couple of NSIntegers and NSStrings (only two or three of each) in NSUserDefaults and then I’m reading those values in different parts of my app (different views) but I was wondering if this is a common practice or should I be doing something different like, read the value somewhere in the app and then try to use a different method to pass that data to other views. I want to learn best programming practices, that’s all.
What is the most common practice when using NSUserDefaults values in multiple parts of your app?
FYI,
I’m familiar with multiple ways to pass data between view controllers such as, delegation, prepareForSegue etc.
Thanks a lot.
I would also recommend, to read it multiple times and do not introduce another layer to hold the data.
The most important aspect is imo the actuality of the data, which might be changed inbetween different invocations.
It is ok to read and even write values to NSUserDefault in multiple places, but it is a better practice to have a global mechanism (like a singleton pattern) to read and write to UserDefaults. this way you'll be guaranteed to have fully synchronized values. all you need to do is to create a new class and add a few Class methods to read and write values from NSUserDefaults.
It is OK, when you call [NSUserDefaults standardUserDefaults] it will return the same object whether you spread the calls everywhere in the app or you encapsulate the access in a class.
I prefer the later as it allows you to have more readable code (and other benefits):
BOOL hasX = [TLPSettings hasPreferenceX];
if (hasX) {
[TLPSettings setY:YES];
}
vs
BOOL hasX = [[NSUserDefaults standardUserDefaults] boolForKey:#"hasX"];
if (hasX) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"hasY"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
You can change the preferences keys easily (without defining consts for them), change the validation or logic of a preference without messing with it everywhere, debug its usage or rogue values easily, store all or part of them in a different place, etc.
TLP is your three letter prefix.
What kind of database do you suggest? I want to store user email, username, password, and a couple other random pieces of information. It doesn't have to be fancy. Just a simple database. Are there any free options?
The user information needs to be stored in the keychain to keep it secure.
Any other information could be stored in any one of:
User defaults NSUserDefaults
File on disk (maybe a plist)
Database Core Data (technically just a file on disk)
Which you choose depends on what the data is, how much there is and what kind of access you need to it.
If your data is small and chosen by the user as some kind of setting then user defaults makes sense and is the lowest cost for you to implement.
To use a database, check out Core Data intro.
Wain is right but I think as you want to store small amount of data for further use, the most efficient ways is to use NSUserDefault.
NSUserDefault stores data in NSDictionary type things.
I think this is the step you have to take:
1- check if data exists. I mean if user selected the number if the last run of your app. So in viewDidLoad method:
NSMutableDictionary *userDefaultDataDictionary = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:ALL_DATA_KEY] mutableCopy];
if (userDefaultDataDictionary) {
// so the dictionary exists, which means user has entered the number in previous app run
// and you can read it from the NSDictionaty:
if(userDefaultDataDictionary[LABLE_KEY]){
//and store it
}
}
2 - you can implement some method like syncronize to store data in NSUserDefault every time something has been changed.
- (void) synchronize
{
NSMutableDictionary *dictionaryForUserDefault = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:ALL_DATA_KEY] mutableCopy];
if(!dictionaryForUserDefault)
dictionaryForUserDefault = [[NSMutableDictionary alloc] init];
dictionaryForUserDefault[LABLE_KEY] = //data you want to store
[[NSUserDefaults standardUserDefaults] setObject:dictionaryForUserDefault forKey:ALL_DATA_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
}
P.S. and don't forget to #define your keys for your dictionary:
#define LABLE_KEY #"Lables"
#define ALL_DATA_KEY #"AllData"
Store it in a plist. If you're talking about data pertaining to one or a few users, that's probably the easy thing. here is a simple example.
Since you say database, store in Sqlite. There's some provided stuff for it already in xcode.
The entire database is contained in one file, which can be moved around if you need to.
Here is some more information on how to use one in your app.