as I get closer to releasing my app, I'm trying to make sure that I'm using stable code to check if the app has been launched before (in order to perform some first time setup). Is this (obviously a no frills method that doesn't take into account app version and updates) pretty much a rock solid way to determine if the app has been launched?
In my app delegate didFinishLaunchingWithOptions method, I perform the following each time:
NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
if(![defaults objectForKey:#"not_first_launch"])
{
NSLog(#"This is the first time the app has been launched.\nPerforming first-time setup procedures...");
[self runFirstTimeSetup];
}
My second question is basically, can I assume that when I release an app update, that the user's documents directory for my specific app's sandbox will be left unerased? Does an app update simply add to the directory, not wipe it clean and re-install? I need the user's files to stick around even when I update the app (pretty obvious) but I don't want to make the wrong assumption and have users lose data every time I release an update.
Thanks!
Yes, that's a good use of NSUserDefaults.
User data is preserved through updates.
Just make sure you keep the data that comes with your app and the data generated during runs in separate bins. So that if you have to change the former (via an app update), the latter remains untouched. For example, don't put both of them in the same SQLite table.
I know you already accepted an answer, but I just wanted to touch on the subject. The way I check if the app is being launched for the first time is like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...normal code...
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults objectForKey:#"kFirstUse"]) {
[defaults setObject:[NSDate date] forKey:#"kFirstUse"];
[defaults synchronize];
}
}
The reason why I wanted to post is because while I check if this is the user's first launch, I also save the date of their first launch. For no extra code, I figured why not save this first launch date. I don't use that info at all in my app, but I was thinking maybe in the future I might. In the future, I was thinking about adding in App Purchase, and I would give the stuff away for free to my initial users; so this allows me to be prepared for the future and accomplish my goal at the same time.
And just for completeness, NSUserDefaults do persist between app updates, just make sure not to change the key to any object, otherwise that object won't be found.
Another good thing to add is that line [defaults synchronize]; - that literally makes the app save that data. The app periodically automatically saves the data, but I like to be safe and know that my stuff is saved.
let me know if you have any other questions
Related
I'm wondering how I can add some kind of setup to my App so when the user launches the App it asks a couple of questions and based on those questions it redirects to a specific view and the next time the app launches it will continue there again.
Is there any way to achieve this, because I'm unsure where I should start searching for.
I did something similar in my last project. There the user had the option to use the application connected with facebook or not. For storing the decision of the user I used a key/value pair in the NSUserDefaults. It's very easy to read/write and its persistently stored in the apps filesystem.
I first checked the NSUserDefaults if the key/value pair already exists.
If not, I did a redirection to a ViewController containing the two buttons (With FB/No FB)
Then depending on the selection of the user I setted the NSUserDefault key.
If yes, I did read the NSUserDefaults and get the value of the key.
Depending on the loaded value I redirected him to the FB ViewController or the the normal one.
Here a short example of reading the NSUserDefaults:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *myString = [prefs stringForKey:#"keyToLookupString"];
Here a short example of writing the NSUserDefaults:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:#"TextToSave" forKey:#"keyToLookupString"];
I guess the only difference to your application is that you have several values to store but for that you can still use the NSUserDefaults. You could also use the CoreData to store the information but I think in that case using the NSUserDefaults is the way to go.
My [NSUserDefaults standardUserDefaults] are not being saved. Everytime I close the app and start it again, it reverts back. I don't have my iOS device handy so I am not sure if this will happen on device, but none of the other apps are doing this in simulator which leads me to believe there's something wrong with my code. I don't know what part of code I should include here, it's just simple add/modify keys in NSUserDefaults and as I said it runs fine during the app, but not after i restart it...
I know I can call synchronize but Apple advices against it and says I should only call it if it's a must... so.
What could be going wrong?
Your process is possibly terminated improperly so that NSUserDefaults do not have a chance to be stored. See also this and mostly this.
The suggestion in the second post I link to is to call synchronize in applicationDidEnterBackground:
Keep also in mind that terminating your app by stopping it in Xcode most often does not save user defaults.
Are you restarting from Xcode / debugger? Try sending the app to background with the Home button first. I think the framework synchronizes automatically then.
I could not understand about the way, you are accessing the NSUserDefault, The static function you used sharedDefaults with NSUserDefault does'nt exist in Apple Documentation
Use As below to access NSUserDefault
[NSUserDefaults standardUserDefaults];
For more read the blog post for using of NSUserDefault.
iPhone Programming Tutorial – Saving/Retrieving Data Using NSUserDefaults
In my application i am using In - App purchases to provide a subscription of 1 year….now i need to save the time and date when the user buys the subscription and need to check when the subscription expires?? i have not used database before is there any other way to store date and time in my application and retrieve it every time the application starts??
You should store the purchase of a subscription on a server, with backup in place, not only on the device.
You might have noticed that if you delete any iPhone app, and later re-install it, then the next download is free. There can be many reasons as to why the user might loose your app, a system update went bad, or whatever.
Apple specifically requires that the user do not loose what they have bought. If you have promised 1 year, then you must make sure they get 1 year no matter what happens to your app. Otherwise Apple can, and will, reject your app.
Storing the expiration date on a server also give the added benefit of protection against users fiddling with your data and granting themselves extended subscriptions.
Start by looking at the In App Purchase Programming Guide.
You can simply store it in NSUserDefaults:
[[NSUserDefaults standardUserDefaults] setObject:[NSDate now] forKey:#"purchaseDate"];
Then retrieve it like such:
NSDate *purchaseDate = [[NSUserDefaults standardUserDefaults] objectForKey:#"purchaseDate"];
And when you're done with it:
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"purchaseDate"];
I'm using [NSUserDefaults standardUserDefaults] for storing application settings.
My questions are:
do those settings are removed on app deletion?
are they kept after an application update (through the
AppStore)?
Because I'm using it to store a password and don't want my users to reset them at each update. Also, I'd like that the only way to reset the password would be to remove the app and re-install it.
Is NSUserDefault the right choice?
Thanks,
Jérémy
Yes, they are removed on app deletion and yes they are kept when an application is updated.
However, you're not advised to store sensitive data in the NSUserDefaults, instead I would look at using the Keychain.
I use NSUserDefaults in my app to allow additional access to my app for my colleagues. They just have to enter the code word in settings and the app is fully opened.
to the point each time I update the app they have to re-enter the code word, so I would say from experience that they are not kept after updates. The values need to be re-entered.
Is there any way to save data without connecting to server on the iPhone? If so, please describe how.
Look at the NSUserDefaults class. It can save primitives and NSArray objects of primitives.
Example, your app might write out before app terminates in your app delegate:
[[NSUserDefaults standardUserDefaults] setString:#"Value" forKey:#"Key"];
And then read it in after launch:
NSString *dataYouNeed = [[NSUserDefaults standardUserDefaults] stringForKey:#"Key"];
Just remember to handle the nil case gracefully (i.e. that the app will keep working immediately after a fresh install or a reset to the user defaults).
Edit: the question has already been more-or-less rewritten. Obviously if you need to store data that will act as your application's model (in the MVC sense), Core Data or sqlite is where you would do best to start looking.
If it's a small number of things, use NSUserDefaults. If it's a lot of stuff, use Core Data.