Remove NSDictionary from NSUserdefaults - ios

I would like to remove an NSDictionary that is stored in NSUserdefaults.
I tried with this :
[NSUserDefaults removeObjectForKey:#"bookmarks"];
But, all my favorites are removed
How can I delete one single favorite?
I found the same question here
- Remove object of NSUserDefault by tableview cell
thanks all

Get the dictionary of bookmarks, creating a mutable copy, so you can modify it:
NSMutableDictionary *bookmarks = [[userDefaults objectForKey:#"bookmarks"] mutableCopy];
Remove the one you want:
[bookmarks removeObjectForKey:#"Bookmark be gone"];
Put the bookmarks back:
[userDefaults setObject:bookmarks forKey:#"bookmarks"];
and sync:
[userDefaults synchronize];
EDIT Following a comment from the OP, it sounds like it might be in an array, rather than a dictionary. The principle is the same:
Get the array of bookmarks, creating a mutable copy, so you can modify it:
NSMutableArray *bookmarks = [[userDefaults objectForKey:#"bookmarks"] mutableCopy];
Remove the one you want (to find the index of the object you probably need to iterate the array. See this question):
[bookmarks removeObjectAtIndex:5];
Put the bookmarks back:
[userDefaults setObject:bookmarks forKey:#"bookmarks"];
and sync:
[userDefaults synchronize];

Related

IOS/Objective-C: Save Custom Array as NSUserDefault

I am trying to save an array of objects into an NSUserDefault without success. When I log out the array before the attempt it is full of object. However, when I try to log out the NSUserDefault it is NULL. Can anyone see what I might be doing wrong? Thanks for any suggestions:
Items *myItems = [mutableFetchedObjects mutableCopy];
NSLog(#"my Items%#",myItems);//LOGS OUT LONG LIST OF ITEMS
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:myItems];
[currentDefaults setObject:data forKey:#"myItems"];
[currentDefaults synchronize];
Items *myRetrievedItems = [[[NSUserDefaults standardUserDefaults] arrayForKey:#"myItems"] mutableCopy];
NSLog(#"my Retrieved Items%#",myRetrievedItems); //LOGS OUT AS NULL
As the other answers mentioned, it is because your array is not complying to the NSDictionary types (string, binary, bool, etc). Your members of array is of custom types therefore it cannot be saved. What you need to do is convert your array to binary first and then save it.
You have to unarchive your data first at the time of retrieving back. You are directly accessing the data. This won't work. You can do it the similar way you are archiving the data
NSData *dataObj = [currentDefaults objectForKey:#"myItems"];
Items *myRetrievedItems = [NSKeyedUnarchiver unarchiveObjectWithData:dataObj];
For more reference, you can consider this answer.
Hope this helps.
Thanks!
Your access value method is wrong.
You can get the array in following code:
Items *myRetrievedItems = [[[NSUserDefaults standardUserDefaults] objectForKey:#"myItems"] mutableCopy];

Deleting NSUserdefault Array from a UITableView

I have an array which saves all the user inputs as an array of Strings using NSUserDefaults. In another view controller this array data can be viewed in a UITableView. Is there any way to delete the record in the array when I delete a row in the UITableView?
please refer the following for more detail.
https://stackoverflow.com/questions/32679088/tableview-nsinternalinconsistency-exception-error
Thanks
try like this in your tableview delete function
NSMutableArray *dataArray = [[NSUserDefaults standardUserDefaults] valueForKey:#"SavedArray"];
[dataArray removeObjectAtIndex:yourIndex];
[[NSUserDefaults standardUserDefaults ] setValue:dataArray forKey:#"SavedArray"];
[[NSUserDefaults standardUserDefaults]synchronize];
Using this code you will delete or resave your array in userdefaults
In your didSelect
NSMutableArray *yourArray=[[NSMutableArray alloc]init];
[yourArray removeObjectAtIndex:indexPath.row];
[self.tableView reloadData];
This is a three step process:
Step 1: Fetch & save your user details in a mutable array:
NSMutableArray *userDetailsArray = [[[NSUserDefaults standardUserDefaults] objectForKey:#"userDetails"] mutableCopy];
Step 2: Update your data array once user delete something. Use any of the below methods:
[userDetailsArray removeObject:<Your_Object>];
[userDetailsArray removeObjectAtIndex:<Your_Index>];
Step 3: Finally save them back in NSUserDefaults:
[[NSUserDefaults standardUserDefaults] setObject:userDetailsArray forKey:#"userDetails"];
[[NSUserDefaults standardUserDefaults] synchronize];
If you want to delete all NSUser defaults just use :-
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)
Based on Apple documentation NSUserDefaults Class Reference "Values returned from NSUserDefaults are immutable, even if you set a mutable object as the value. For example, if you set a mutable string as the value for "MyStringDefault", the string you later retrieve using stringForKey: will be immutable"

How can I allow users to duplicate arrays each with a different user selected name?

My app allows users to create and several several arrays, from the media picker, saving each with a different user selected name. How can I allow the user to make a duplicate of one of the arrays and save under a different file name?
example list shows user created arrays
array1
array2
array3
Now the user wants to create a new array just like array3 but they will delete a few items rather than create an entire new array.
So I want the user to be able to make a copy of array3 naming it array4 and then make a be able to a few changes to array4 and save time.
Hope that makes some sense.
After the media picker selection of songs, this is my save playlist method:
- (void)savePlaylist:(MPMediaItemCollection *) mediaItemCollection
{
NSArray* items = [mediaItemCollection items];
if (items == nil)
{
return;
}
NSMutableArray* listToSave = [[NSMutableArray alloc] initWithCapacity:0];
for (MPMediaItem *song in items)
{
NSNumber *persistentId = [song valueForProperty:MPMediaItemPropertyPersistentID];
[listToSave addObject:persistentId];
}
//read playlist title
NSUserDefaults *defaults;
defaults = [NSUserDefaults standardUserDefaults];
NSString *thissongsList;
thissongsList = [defaults objectForKey:#"savetextkey"];
//save playlist
defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject: thissongsList forKey:#"savetextkey"];
[defaults synchronize];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject: listToSave];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:_songsList];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Asking to duplicate an array is fine, but we don't even know what language you're using. If you are using Objective-C, then all you have todo in order to copy an array is send the "copy" command on an array. Example below.
NSArray *myArray = [oldArray copy];
This is called a "shallow copy" which means it'll only copy the pointer references and not the actual objects. If you need to make brand new instances of the objects, then you'll need to adopt the NSCopying protocol in your objects, and override the copyWithZone method.
If you are using Swift then you'll basically do the same thing. To copy the array you'll use the code below.
var myArray = oldArray
Then use the same NSCopying protocol if you want to make a deep copy.
That's it, that is all you've got todo to copy an array.
Thanks

NSUserdefaults multiple data types for one key

After reading from various answers I have come to know that NSUserDefaults can save multiple datatypes for one key. But what I cannot find is if
[NSUserDefaults standardUserDefaults] removeObjectForKey:"someKey"];
removes all objects of all data types associated with that key?
You cannot store different kind of objects for one key.
If you set an object for a key it will erase the old one.
But, if your are searching for a way to store multiple data for one key, you can store a NSDictionary.
Ex :
MyObject *obj = [[MyObject alloc] init];
NSString *otherType = #"mystring";
NSDictionary *multipleData = #{ #"key1" : obj , #"key2" : otherType}
[[NSUserDefaults standardUserDefaults] setObject: multipleData forKey:#"multipleData"];
[[NSUserDefaults standardUserDefaults] synchronize];
And if you want to remove it :
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"multipleData"];
[[NSUserDefaults standardUserDefaults] synchronize];
Yes it does.
Your data may be anything an array or dictionary or simple int. This command will remove that data.
As iPatel suggested. You need to call:
[[NSUserDefaults standardUserDefaults] synchronize];
After adding or deleting any data. Hope this helps.. :)
You cannot store multiple objects under one key. NSUserDefaults acts just like a NSDictionary. When you set an object for a specific key you overwrite the old object. So removeObjectForKey: just removes one object/value; the one you had stored under that key.
Do you call
[[NSUserDefaults standardUserDefaults] synchronize];
after delete all the data of the key and also might be you can not store multiple data on single key, it's return new one that inserted to last. ?
Read official documentation of removeObjectForKey of NSUserDefaults.
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSString *yourDomain = [[NSBundle mainBundle] bundleIdentifier];
[userDefault removePersistentDomainForName:yourDomain];
Here. if u want to reset.

NSMutableArray adding elements get overwritten in iPhone

I'm trying to add elements to an NSMutableArray whenever a user selects a country. But each time I use [myarray setobject:#""];, it's adding the new value, overwriting my old value. I want this array as I'm using it in:
[[NSUserDefaults standardUserDefaults]setObject:(NSMutableArray *)selectedCountriesByUser forKey:#"userSelection"];
[[NSUserDefaults standardUserDefaults]synchronize];
I want an array which maintains the list of countries selected by the user even after the application is closed.
What should I do?
setObject replace all objects in array
for example, get value from NSUserDefault:
NSMutableArray *myMutableArray = [NSMutableArray arrayWithArray:[[NSUserDefault standardUserDefault] objectForKey:"userSelection"]];
you should use [myMutableArray addObject:"aCountry"]; without overwriting, but adding only
and after
[[NSUserDefaults standardUserDefaults]setObject:myMutableArray forKey:#"userSelection"];
[[NSUserDefaults standardUserDefaults]synchronize];
EDIT:
-(void) viewDidLoad {
//your selectedCountriesByUser
myMutableArray = [NSMutableArray arrayWithArray:[[NSUserDefault standardUserDefault] objectForKey:"userSelection"]];
}
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//add object to array
[myMutableArray adObject:"yourObj"];
[[NSUserDefaults standardUserDefaults]setObject:myMutableArray forKey:#"userSelection"];
[[NSUserDefaults standardUserDefaults]synchronize];
}
You're asking two different things. First, -setObject: is not a NS(Mutable)Array method. You are probably looking for the -addObject: method. So, to add an object to your NSMutableArray, you need to do:
[myMutableArray addObject:yourObject]
//Remember that `-addObject` is present only in NSMutableArray, not in NSArray
The second thing you are trying to achieve is to store the array in NSUserDefaults. to do so, after you add the object to the array you want, you should be fine do to so:
[[NSUserDefaults standardUserDefaults] setObject:myMutableArray forKey:#"userSelection"];
[[NSUserDefaults standardUserDefaults] synchronize];
// ARRAY DECLARATION AND ASSIGNMENT OF VALUES TO IT
NSMutableArray * selectedCountriesByUserArray=[[NSMutableArray alloc] init];
[selectedCountriesByUserArray addObject:#"value1"];
[selectedCountriesByUserArray addObject:#"value2"];
[selectedCountriesByUserArray addObject:#"value3"];
// STORING AN ARRAY WITH THE KEY "userSelection" USING NSUSERDEFAULTS
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:selectedCountriesByUserArray forKey:#"userSelection"];
[defaults synchronize];

Resources