using didSelectRowAtIndexPath to push saved data viewcontroller - ios

I have a tableview that show saved data, but when I try to go from selected cell, it doesn't show the data that's been saved. It try this
I used NSUserDefaults to save data in other view (another .m file)
- (IBAction)saveCourseDetail:(id)sender
{
NSMutableDictionary *courseDictionary=[NSMutableDictionary new];
[courseDictionary setObject:courseName.text forKey:#"courseName"];
[courseDictionary setObject:courseDescription.text forKey:#"courseDescription"];
[courseDictionary setObject:classRoom.text forKey:#"classRoom"];
[courseDictionary setObject:teacherName.text forKey:#"teacherName"];
[courseDictionary setObject:buildingName.text forKey:#"buildingName"];
[globArray addObject:courseDictionary];
NSUserDefaults *savedData=[NSUserDefaults standardUserDefaults];
[savedData setObject:globArray forKey:#"array"];
// [savedData setObject:courseDictionary forKey:#"courseDictionary"];
[savedData synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName:#"CourseAddedNotification" object:nil];
[self.navigationController popViewControllerAnimated:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
CourseDetailViewController *courseDetails=[[CourseDetailViewController alloc]init] ;
courseDetails.savedDataDic = [globArray objectAtIndex:indexPath.row];
[self.navigationController pushViewController: courseDetails animated:YES];
}
My problem is that I cant go from a selected cell to the view that the data's been saved.

I personally recommend you to use core data if there is large amount of data to be stored. Using user defaults is not good to store large chunks of data. Anyways, if you want to store an array of dictionary, you have to encode it and to read the array you have to decode it like this
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *arr = ... ; // set value
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr];
[defaults setObject:data forKey:#"theKey"];
Load:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:#"theKey"];
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];
The element in the array implements
#interface DictionaryItems : NSObject<NSCoding> {
NSString *value;
}
Then in the implementation of CommentItem, provides two methods:
-(void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:value forKey:#"Value"];
}
-(id)initWithCoder:(NSCoder *)decoder
{
self.value = [decoder decodeObjectForKey:#"Value"];
return self;
}
Hope it helps :)

Related

Empty NSCFConstantString in stored UserDefaults

I have a problem with a stored userDefaults array.
I have a simple object (in the image I have cut off some variables) with two strings mutableArray.
When I save this object in the userDefaults I have the same object in the top (of the image), the problem occurs when I retrieve the object; I have the object in the bottom (added by me in a mutableArray, same object before add it).
the problem is that I make comparisons between objects and it returns false because there is an empty NSCFConstantString in the second array.
These are the two methods to store and retrieve the object in the userDefaults:
- (void)saveCustomObject:(NSMutableArray *)object key:(NSString *)key
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:object] forKey:key];
[defaults synchronize];
}
- (NSArray *)loadCustomObjectWithKey:(NSString *)key
{
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:key];
NSMutableArray *objectArray = nil;
if (dataRepresentingSavedArray != nil)
{
NSArray *savedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (savedArray != nil)
objectArray = [[NSMutableArray alloc] initWithArray:savedArray];
else
objectArray = [[NSMutableArray alloc] init];
}
return objectArray;
}
I would prefer not to have to write logic to handle this empty string.
Where is it coming from?

Objective C - Saving a variable inside NSUserDefaults

I have a class called "EntityType" that has a string "name" and I am using NSUserDefaults to save it so I tried this:
if (button.selected)
{
[button setSelected:YES];
[[NSUserDefaults standardUserDefaults]setObject:[NSNumber numberWithBool:YES] forKey:#"buttonSelected"];
}
I want to access the variable from another class and save it inside NSUserDefaults
You have missed sync call.Apply this to save it.
if (button.selected)
{
[button setSelected:YES];
[[NSUserDefaults standardUserDefaults]setObject:[NSNumber numberWithBool:YES] forKey:#"buttonSelected"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
to get it back later
NSNumber* savedValue = [[NSUserDefaults standardUserDefaults]
objectForKey:#"buttonSelected"];
This is if you want to store only the value.
If you want to store your custom object look at this link
How to store custom objects in NSUserDefaults
You can get NSNumber object like,
NSNumber *num = [[NSUserDefaults standardUserDefaults] objectForKey:#"buttonSelected"];
from anywhere in the app.
On your EntityType class, implement the following two methods for encoding and decoding (something relevant to your own object):
- (void)encodeWithCoder:(NSCoder *)encoder {
//Encode properties, other class variables, etc
[encoder encodeObject:self.name forKey:#"name"];
}
- (id)initWithCoder:(NSCoder *)decoder {
if((self = [super init])) {
//decode properties, other class vars
self.name = [decoder decodeObjectForKey:#"name"];
}
return self;
}
Reading and writing from NSUserDefaults:
- (void)saveCustomObject:(MyObject *)object key:(NSString *)key {
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:object];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:encodedObject forKey:key];
[defaults synchronize];
}
- (MyObject *)loadCustomObjectWithKey:(NSString *)key {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *encodedObject = [defaults objectForKey:key];
MyObject *object = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];
return object;
}
Code borrowed from: save class in NSUserDefaults
**ViewController.h**
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
//here i took one userdefault property
#property(strong,nonatomic)NSUserDefaults *user;
#end
**ViewController.m**
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//after the property declaration take standard user defaults
_user = [NSUserDefaults standardUserDefaults];
//here i took Bool and key you can take any thing but took my_val
[_user setBool:YES forKey:#"my_val"];
}
// this is button action
- (IBAction)submit:(id)sender
{
//for bool i am checking the condition given above
if ([_user boolForKey:#"my_val"])
{
**enter code here**
NSLog(#"values is set to yes");
}
else
{
**enter code here**
NSLog(#"Value is set to No");
}
}

Obj C - NSUserDefaults won't give back values to calculate, after loading the view

I am stuck with little problem. I have basic calculating app.
Viewcontroller.m
#import "ViewController.h"
#interface ViewController () <UITextFieldDelegate, UIAlertViewDelegate>
#end
#implementation ViewController
-(void)textFieldDidEndEditing:(UITextField *)textField
{
self.currentSettings = _currentSettings;
[self calculateThePrice];
}
-(void)calculateThePrice
{
float wynik = self.currentSettings.kwh * self.currentSettings.price;
self.priceLabel.text = [NSString stringWithFormat:#"%.02f %#", wynik , self.currentSettings.currency];
}
SettingsVC.m
#import "SettingsVC.h"
#interface SettingsVC () <UITextFieldDelegate>
#end
#implementation SettingsVC
#pragma mark - UserDefaults Implementation
-(void)viewWillAppear:(BOOL)animated
{
[self createCurrencyArray];
NSUserDefaults *priceDef = [NSUserDefaults standardUserDefaults];
NSString *priceDefText = [priceDef stringForKey:#"priceCall"];
_priceTextField.text = priceDefText;
NSUserDefaults *currencyDef = [NSUserDefaults standardUserDefaults];
[_currencyPicker selectRow:[currencyDef integerForKey:#"currencyCall"]
inComponent:0 animated:NO];
[priceDef synchronize];
[currencyDef synchronize];
}
-(void)viewWillDisappear:(BOOL)animated
{
NSString *textOfPriceTexField = _priceTextField.text;
[[NSUserDefaults standardUserDefaults] setObject:textOfPriceTexField forKey:#"priceCall"];
}
Now, the problem is when I want program to automatically-calculate, it won't. To have any result, I have to switch to Second View, choose a value from picker and then when I will go back, I have my result.
But...
- When I change value on 1st screen, result won't change. When I change value on 2nd scree, result won't change. But when I change value on PickerView - TADAH - result updates!
When I go to second view, and go back to first, then go again to second and go back to first, my result changes to "0.00 (NULL)"...
Any ideas where I did wrong? I think it is about NSUserDefaults, I tried many options, nothing worked, nor changed anything.
You need to synchronize NSUserDefaults when you set new values. You are using synchronize when you retrieve values.
Here you don't need 2 pointers to defaults and don't need synchronize:
NSUserDefaults *priceDef = [NSUserDefaults standardUserDefaults];
NSString *priceDefText = [priceDef stringForKey:#"priceCall"];
_priceTextField.text = priceDefText;
[_currencyPicker selectRow:[priceDef integerForKey:#"currencyCall"] inComponent:0 animated:NO];
Here you need synchronizes:
-(void)viewWillDisappear:(BOOL)animated
{
NSString *textOfPriceTexField = _priceTextField.text;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:textOfPriceTexField forKey:#"priceCall"];
[defaults synchronize];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSInteger selectedRow = [_currencyPicker selectedRowInComponent:0];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:selectedRow forKey:#"currencyCall"];
[defaults synchronize];
self.currentSettings.currency = [self.currencyArray objectAtIndex:row];
self.currentSettings.price = [self.priceTextField.text floatValue];
//[self userDidFinishSetting];
}
Try this code
-(void)viewWillDisappear:(BOOL)animated
{
NSString *textOfPriceTexField = _priceTextField.text;
[[NSUserDefaults standardUserDefaults] setObject:textOfPriceTexField forKey:#"priceCall"];
}
-(void)viewWillAppear:(BOOL)animated
{
[self createCurrencyArray];
NSUserDefaults *priceDef = [NSUserDefaults standardUserDefaults];
NSString *priceDefText = [priceDef objectForKey:#"priceCall"];
}
instead of stringForKey you can call objectForKey same as for integerForKey also you can call objectForKey. Actually you are setting the object not string or integer.

NSCoding save NSMutableArray on shutdown and load on startup

I am trying to save a NSMutableArray when the app shuts down, and then load it on startup to a tableview.
Here's my code:
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:_savedText forKey:#"savedText"];
}
- (id)initWithCoder:(NSCoder *)decoder {
if((self = [super initWithCoder:decoder])) {
_savedText = [decoder decodeObjectForKey:#"savedText"];
}
return self;
}
I use this code to save the MutableArray:
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_savedText];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"savedText"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
And this to load it:
- (void)viewDidLoad {
NSData *savedData = [[NSUserDefaults standardUserDefaults] objectForKey:#"savedText"];
NSMutableArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:savedData];
array = [_savedText copy];
}
There are no errors, but the table view is empty on startup. Have I forgotten something?
You should read the data from the defaults and set to _savedText object. You are reading the data into var named array and then assigning array = [_savedText copy]. This will probably be nil. It should be the reverse.
- (void)viewDidLoad {
NSData *savedData = [[NSUserDefaults standardUserDefaults] objectForKey:#"savedText"];
NSMutableArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:savedData];
_savedText = [array copy];
}

Saving data with NSUserDetaults and load after phone restart wont work

I managed to save an NSMutableArray in NSUserDefaults by first converting it to NSData - I dont deal with a lot of data and just want the data to be there after I switch off & on my phone - but the data does not show up in my table where I would display it. I write the NSUserDefaults back to my array upon loading. Maybe one of you has a hint...? Below the button action where I write to NSUserDefaults and the method viewDidLoad where I write NSUserDefaults to my original array (toDoitems)
- (IBAction)unwindToList:(UIStoryboardSegue *)segue
{
XYZAddToDoItemViewController *source = [segue sourceViewController];
XYZToDoItem *item = source.toDoItem;
if (item !=nil) {
[self.toDoitems addObject:item];
NSString *error;
NSData *data = [NSPropertyListSerialization dataFromPropertyList:self.toDoitems format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"itemArray"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self.tableView reloadData];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.toDoitems = [[NSMutableArray alloc] init];
self.toDoitems = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"itemArray"]];
}
Heres one way to do this
Add encoder decoder functions to your XYZToDoItem class
Something like this if say you had 2 strings in this class string1 and string2 :
(i havent compiled this code but you get the idea)
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.string1 forKey:#"string1"];
[aCoder encodeObject:self.string2 forKey:#"string2"];
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self)
{
self.string1 = [aDecoder decodeObjectForKey:#"string1"];
self.string2 = [aDecoder decodeObjectForKey:#"string2"];
}
return self;
}
Then when you are ready to save do the following
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self.myDataArray];
[userDefaults setObject:data forKey:#"storageName"];
// To load the data from NSUserDefaults
NSData *myData = [[NSUserDefaults standardUserDefaults] objectForKey:#"storageName"];
NSArray *temp = (NSMutableArray*)[NSKeyedUnarchiver unarchiveObjectWithData:myData];
self.myDataArray = (NSMutableArray*)[temp mutableCopy];

Resources