I have an app that needs to keep hold of how many people have joined a room, my problem is keeping a hold of this value. I need to increment this value by one every time the user joins. So i need to check that the room is not full.
I have been thinking of using sessions and keeping track of this value in php, but is there another way natively, so my question is how do i retain or persist this value?
I tried this running on two phones but the value is always 1 when the global value (myData) should be 2 when the second phone runs the app:
myData = myData + 1;
[[NSUserDefaults standardUserDefaults] setObject:[NSString stringWithFormat:#"%d", myData] forKey:#"myData"];
NSLog(#"%d",myData);
If you want to synchronise information between the devices in your case, you should update the data using your server (or how you handle the networking between the devices and rooms etc.)
For example if you install the app in a new phone, it should firstly fetch the value from your server and save the NSUserDefaults so that it can be synchronised.
However, with this way, I don't think you need to store data in the phone, so you can directly use information from server to check the room fullness etc. Storing as NSUserDefaults looked unnecessary to me.
I hope I got the question and your app right.
Related
I save the user profile picture ID of a user as a string in NSUserDefaults e.g. #"12". When I do that, I call the synchronize method immediately.
When I read this value from NSUserDefaults, it returns #"12" in maybe 99% of the time. But sometimes, it returns a different value (which I cannot find due to the rarity of the event, but suspect it is either nil or some default value (?)).
The code I use to write/read is very simple:
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:#"12" forKey:#"photoID"];
[userDefaults synchronize];
NSString* photoID=[userDefaults objectForKey:#"photoID"];
I know the value sometimes returned is incorrect because the app at the time behaves as if the value was different (i.e. user contacts are notified the profile picture has changed).
And when that happens, the next call to objectForKey returns the correct value, so user contacts received another notification the profile picture has changed again.
NSSynchronize is not guaranteed to succeed and returns a BOOL.
Note that syncrhonize simply writes the data to disk but NSUserDefaults keeps the data in memory as well. Calling it after every write is probably not needed, though I've done it myself and many examples on the net do that.
From the Apple documentation:
use this method only if you cannot wait for the automatic synchronization (for example, if your application is about to exit) or if you want to update the user defaults to what is on disk even though you have not made any changes.
Disclaimer: speculation
It's possible that the act of failed synchronize is causing objectForKey to fail. The class knows the data it has may be wrong and so returns nil instead. This is more likely if you are calling synchronize successively and excessively or otherwise doing IO intensive operations.
I'm developing a Point of Sale-kind-of-app, which runs on iOS and stores orders and payments in MySQL. I designed the order-table so that there is a client ID and a ClientOrderID which is a combined unique index, preventing duplicate sales.
The iPad gets its Client ID the first time it connects to the server and validates. This means no two iPads will ever get the same Client ID. If they reconnect they get a new one which is from a an auto-increment value of a column in another table designed for this.
Now, the client must of course also have a ClientOrderID to deliver to the server, so that the unique index becomes useful. What I did here is create a static method that looks like:
+(int)getNewOrderOrSaleID {
int orderid = [[NSUserDefaults standardUserDefaults] integerForKey:#"orderid"];
[[NSUserDefaults standardUserDefaults] setInteger:orderid+1 forKey:#"orderid"];
[[NSUserDefaults standardUserDefaults] synchronize];
return orderid;
}
My questions is now this: Is this a reliable method, or does NSUserDefaults tend to mess things up?
And this is probably a bit far out, but doing this every time someone makes an order from the iPad, would that cause wear on the internal storage over time? This question is close to rhetorical, as I do realize how small the data amount is.
As it's only possible to make one order at a time, this method will never run two times at once.
Since you are overwriting the same thing, you won't have new records in the user defaults, the existing one will change. And if you want to persist only some small information (like this int) the user defaults is a good place to do it. However, as Wain mentioned in the comment, the counter will be reset when you reinstall the app.
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
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.