How to reset Contents and Settings in an OS X app? - ios

I need to reset by database and userdefaults value in my OS X app. How can I do it? In IOS app we have an option like 'Reset contents and settings'. But I don't see such an option when I run OS X app. What I'm doing right now is, drill down to /users/library and delete the .storedata file under my project folder. But with this method I am not able to reset my userdefaults value. Is there any other way out? I am new to OS X programing.
Thanks in advance!

You will need to manually nil the values of your NSUserDefaults and delete the database al-together and then recreate it. Best option would be to include an empty database and copy it over to the Library folder (or wherever you access it) if it does not exist.

I have this in a DebugViewController:
- (void)removeUserDefaults {
[[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]];
}
Then I can delete the UserDefaults with a Button-Press.

Related

iOS: App Groups missing user default key

I have an App with a today extension. I created already an app group in the developer portal and created the target in my xcode project, linking the group in the capabilities for my app and today target.
So at the app side I'm saving my values like this:
NSUserDefaults *prefs = [[NSUserDefaults alloc] initWithSuiteName:suite];
[prefs setObject:value forKey:key];
[prefs synchronize];
The suite property is the name of my group created in the developer portal. Value is a NSDictionary.
NSDictionary* savedDict = [prefs objectForKey:key];
Calling this gives me the correct values
At the Extension Side I'm using swift and trying to get my UserDefaults like this
let userDefaults = UserDefaults.init(suiteName: "group.cryptochange.favorites")
let savedDict = userDefaults?.dictionary(forKey: "Favorites");
The problem is, that savedDict is nil.
When I print out all keys in my user defaults I see the "Favorites" key at the app side but if I'm printing out the keys in the extension, this key is missing.
Does anybody know where or what the problem could be?
Thanks in advance
EDIT 1:
I just recognize that it works with a debug build but not when I change the scheme to release
EDIT 2:
I just checked the documents directory of my app and see my app groups file which includes the values I saved.
When I look up at the documents dir of the extension there is no such a file. Is this works as intended?
After I set an "test" value inside my extension code the file appears with the test value
You have to make sure:
suite = "group.cryptochange.favorites"
key = "Favorites"
You have to check Extension is a member of group app
You should review that "Cast type" is correct
I hope my answers are useful

NSUserDefaults Not Saving Data. Limits?

I have such a problem: the syntax of saving data in userDefaults is clear and was working everyday in app. Today i have such a problem that nothing is stored after synchronize. P.S i have no syntax error.
here is an example of saving and reading:
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"StackOverflow"];
[[NSUserDefaults standardUserDefaults] synchronize];
And reading
BOOL stackOverflow = [[NSUserDefaults standardUserDefaults] boolForKey:#"StackOverflow"];
I know information about mutableCopy but in this simple situation it's not needed.
So is there any limits for userDefaults? I am testing on real device and storage i have up to 50GB free. I know that userDefaults are stored in plist file which in critical situation could be 1MB but i even dont exceed 1kb :( ...
using latest xcode and latest iOS version on 6S.
Need Advice. Thanks For help.
So after half hour morning work i find the solution and actually the problem. Case such as mine in 90% it is developers fault, so it was.
I had more than 30 user defaults value's, in which for e.g 15 of them had initWithSuitName (Identifier), everything saved with identifier id was working well but saving value without it was broken because of preferance conflicts.
Solution: I replaced unnamed userDefaults with identifier and everything has fixed.
In Case of some problem with NSUserDefaults:
NSUserDefaults - is thread safe.
Synchronize - Saves data immediately
Saving Data - If app will terminate chance of losing data is 50%, after debug Stop button tapped is same scenario. P.S data lose will be 50% if it's not saved in right place.
Debuging NSUserDefaults - in debugger you can simply tipe po [[NSUserDefaults standardUserDefaults] dictionaryRepresentation] and po [[NSUserDefaults standardUserDefaults] valueForKey:#"KeyForSavedData"]
Shared Container Example - if you want to share property for example between app and extension you can simply type appGroup identifier inside initWithSuitName:#"com.Example.ExampleAPP"
I faced this issue before. I just remove the key before add it to new object.
Example
[NSUSER removeObjectForKey:#"savedData"];
[NSUSER setBool:YES forKey:#"savedData"];
[NSUSER synchronize];
Note:
If you are used so many no of NSUSER then it act like ridicules. This is by my little experience.

Determine if you own app is currently installed or not programmatically

I am creating a new feature in one of my apps to show a "What's New" page. I have this all working as expected and it compares the last version (stored) to the current version, then updates the current version once the feature list is shown.
This all works great and as expected. The issue I have now is determining if a user already has the app installed.
Case 1) If the user is a completely new user and it is the first time they have downloaded the app, then the new feature list should not be shown.
Case 2) If they already had the app installed and are updating their app to a new version, then we need to show the new feature list.
The part I need help with is Case 2. How can you determine if the app is already installed by the user, without having to release a minor update just to set a currentInstalledVersion variable beforehand?
if(currentInstalledVersion)
{
if(currentInstalledVersion < actualCurrentVersion)
{
// user upgraded
}
}
else
{
if(someOtherDataSavedOnDiskExists)
{
// user had the app with a version before you implemented currentInstalledVersion and is updating
}
else
{
// fresh install
}
}
Update based on below comment
Okay in that case, there is no built-in mechanism to help you with this. Until you implement a way yourself (with this flag), you can't check. However, if you have any kind of other flags or data you've written to NSUserDefaults for instance, you can check that immediately on startup to see if those values are set which would tell you it is an existing user that just installed the app (only check the other flags if currentInstalledVersion is not set). If you have not written any data to disk or to NSUserDefaults then you are out of luck for your initial release of this feature.
I updated the code above to reflect this.
You could use NSUserDefault and set a bool to check if it's a new user.
ex:
if(![[NSUserDefaults standardUserDefaults] boolForKey:#"user"]){
// it's a new user
[[NSUserDefaults standardUserDefaults] setBool:YES ForKey:#"user"];
}
The boolForKey: method would return NO if the default was not set.

How to force delete NSUserDefaults when app is updated?

If a new version is not backward compatible with previous version's data, what is the best way to ensure NSUserDefaults is deleted upon upgrade?
A simple way would be to keep a default that tracks whether the upgrade process has been performed. The new version would check for it, and if it hasn't been set, perform the upgrade procedure and set the value to make sure the process isn't performed twice. Like this:
static NSString * const kUserDefaultsDidUpgradeKey = #"didUpgrade";
NSUserDefaults *ud = NSUserDefaults.standardUserDefaults;
if (![ud boolForKey:kUserDefaultsDidUpgradeKey]) {
// Delete the keys here
[ud setBool:YES forKey:kUserDefaultsDidUpgradeKey];
}
However, assuming that you would want to handle other version migrations in the future, a more robust way would be to write the app version to user defaults so that when the app is updated, the new version can check the version key to see what the previous version was, and run the upgrade process accordingly.

is that possible to know my apps is first time run or not in xcode?

i create an apps that i want to prompt an message for the user.. maybe using UIAlertview. After that, if the user run the apps for the second time, the alert won't prompt up anymore.
is that possible? honestly i don't have any idea about how to doing this.
Any idea? I search on STO, actually this link, still confused.
what is NSUserDefaults? How can NSUserDefaults store this information? i mean this is my first time or second time.
thanks.
To know what's NSUserDefaults, I suggest to take a look the official doc.
And of course you can use it to fulfill your goal.
You use a user default to store information about the current amount of runs in the app.
More or less like:
BOOL isRunMoreThanOnce = [[NSUserDefaults standardUserDefaults] boolForKey:#"isRunMoreThanOnce"];
if(!isRunMoreThanOnce){
// Show the alert view
// Then set the first run flag
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"isRunMoreThanOnce"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Yes, U can save a value in NSUserDefault for the first time in your app & set it some other value once you open the app.
like
if(![[NSUserDefault standardUserDefault] objectforKey:#"AppOpenFirstTime"])
{
// App Open First time
// Show Alert
[[NSUserDefault standardUserDefault] setObject:#"1" forKey:#"AppOpenFirstTime"]
}
You can check if you stored some value in NSUserDefaults
NSString *flag = [[NSUserDefaults standardUserDefaults] stringForKey:#"not_first_run"];
if (!flag) {
//first run, do somethig
}
and then set it to some value
[[NSUserDefaults standardUserDefaults] setObject:#"just any string" forKey:#"not_first_run"];
NSUserDefaults is a key-value store saved between your application launches.
You can do it exactly as cortez said in your link. NSUserDefaults is written to disc, and will be created and accessed from your app.
See this link
First Time when your application launch at that time boolForKey:#"AlreadyRan" is FALSE. after that set it TRUE.
if(![[NSUserDefaults standardUserDefaults] boolForKey:#"AlreadyRan"] )
{
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:#"AlreadyRan"];
}
With the NSUserDefaults class, you can save settings and properties
related to application or user data.
The objects will be saved in what is known as the iOS “defaults system”.
The iOS defaults system is available throughout all of the code in your app, and any data saved to the defaults system will persist through application sessions.This means that even if the user closes your application or reboots their phone, the saved data will still be available the next time they open the app!

Resources