NSUserDefaults error for "objectAtIndex" - objective-c

Getting an error message on this line of code:
Team *team = [leagueLocal.teams objectAtIndex:indexpath.row];
Error is "Use of undeclared identifier 'indexpath'"... but I'm not sure what I would put at objectAtIndex: other than indexpath.row, because thats what works for me in the TableView part of this app.
Big picture, I'm trying to use NSUserDefaults save the Team Name that was selected. Team Names are being pulled in via JSON from a web service.
Here is the full code for the NSUserDefaults part I have so far:
// Create User Defaults Variable
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// Tell it where to look
Sport *sportLocal = [sports objectAtIndex:0];
League *leagueLocal = [sportLocal.leagues objectAtIndex:0];
Team *team = [leagueLocal.teams objectAtIndex:indexpath.row]; // This is where error is
// Store the data, this is the stuff I want to save
[defaults setObject:team.abbreviation forKey:[NSString stringWithFormat:#"teamAbbreviation%d", _buttonNumber]];
// After saving, synchronize data
[defaults synchronize];
Thanks for the help! Let me know if any more info is needed, or where I can help clarify if needed.
Edit- I added an NSLog in my viewDidLoad right below the error to see what I was getting, and it came back null: NSLog(#"object at index: %#", team.abbreviation);

If this is inside viewDidLoad, then unless you've initialized the indexPath variable it will not be valid. It's only valid in your tableView methods because it's passed in through the function.
You have a couple options to grab the indexPath that your looking for though:
Team *team = [leagueLocal.teams objectAtIndex:[NSIndexPath indexPathForRow:i inSection:k];
//where i and k are integers that indicate the row/section for the tableViewCell your looking for...(k would just be equal to 0 if you only have one section)
Or another way would be if the user has previously selected what your looking for then you can use:
NSIndexPath *indexPath=[self.tableView indexPathForSelectedRow];
Team *team = [leagueLocal.teams objectAtIndex:indexPath.row];//now you can use it the way you have it written in your question
Hope it helps!

Related

How exactly to save and retrieve last seen message timestamp - plist or NSUserDefaults

I have two UIViewControllers. In the FirstViewController, I download the groupsInfo data from the firebase and show the details(groupName,lastMessage) in the UITableView and have one more label "lastMessageTime"(this information will come from SecondViewController).Once I tap the UITableView cell, it goes to the detail page SecondViewController, here I download the messageInfo based on the tapped groupID. When I leave the SecondViewController, I want to store the last message time for that particular groupID in commonplace (either plist or NSUserDefaults) and retrieve the information in the FirstViewController or in some other ViewController(later stage). The saved data shouldn't get deleted and also I should be able to update(in case value already exist for particulat key) "lastMessageTime" for any particular groupID whenever there is new message.
Below is code I tried, but not sure if this is the best approach. Would be great if you can tell me the best approach to deal this requirement effectively.
SecondViewController:
-(void)viewWillDisappear:(BOOL)animated{
[self updateLastMessageSeenTime:groupID];
}
-(void)updateLastMessageSeenTime:(NSString*)groupID
{
FIRDataSnapshot *snapshot = [self.messageArray lastObject];
NSMutableDictionary *lastSeenMessageTime = [[NSMutableDictionary alloc]init];
NSString *lastMessageTime = snapshot.value[#"timeStamp"];
[lastSeenMessageTime setValue:lastMessageTime forKey:groupID];
NSUserDefaults *lastSeenMessageTimeUserDefaults = [NSUserDefaults standardUserDefaults];
[lastSeenMessageTimeUserDefaults setObject:lastSeenMessageTime forKey:#"lastMessageTimeArrayKey"];
[lastSeenMessageTimeUserDefaults synchronize];
}
Above method erases all the previous data. For Example, If visited the SecondViewController twice each for different groupID, previous groupID's lastMessageTime is removed and replaced with the new groupID's.
You need to get the dictionary from NSUserDefaults first and if it doesn't exist then init a new one. Try this.
-(void)updateLastMessageSeenTime:(NSString*)groupID
{
FIRDataSnapshot *snapshot = [self.messageArray lastObject];
NSUserDefaults *lastSeenMessageTimeUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *key = #"lastMessageTimeArrayKey";
NSMutableDictionary *lastSeenMessageTime = [[lastSeenMessageTimeUserDefaults objectForKey: key] mutableCopy];
if (!lastSeenMessageTime) {
lastSeenMessageTime = [[NSMutableDictionary alloc] init];
}
NSString *lastMessageTime = snapshot.value[#"timeStamp"];
[lastSeenMessageTime setValue:lastMessageTime forKey:groupID];
NSUserDefaults *lastSeenMessageTimeUserDefaults = [NSUserDefaults standardUserDefaults];
[lastSeenMessageTimeUserDefaults setObject:lastSeenMessageTime forKey: key];
[lastSeenMessageTimeUserDefaults synchronize];
}

Writing in NSUserDefault and .plist failed

I'm having trouble getting some informations written in my .plist, and NSUser Defaults Files.
For the .plist i've already posted but, nothing seems to be wrong:
How to update an array set into the .plist dictionary
And for the NSUser Default, i'm doing something like this:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *userSettings = [[NSMutableArray alloc]initWithArray:[[defaults objectForKey:#"userSettings"]mutableCopy]];
[userSettings addObject:userSettingsArray];//adding an array into my userSettingsArray (declared higher in the code)
[defaults setValue:userSettings forKey:#"userSettings"];
[defaults synchronize];
I was wandering, is there any option in Xcode allowing , or not, the user to write into the app folders?
I'm a little stuck here
Thank you for your help,
Tim
Use
[defaults setObject:userSettings forKey:#"userSettings"];
instead of
[defaults setValue:userSettings forKey:#"userSettings"];
I found the solution to my problem:
I entered the datas from the IBOutlet like this
[self.tempUserSettings insertObject:self.firstName atIndex:1];
instead of this:
[self.tempUserSettings insertObject:self.firstName.text atIndex:1];
so the datas were wrong, and so and so.....
Thank you for you help, learned a lot from those .plist and NSUserDefault

Empty value in NSUserDefaults

I am developing a cocoa application. I created a user default object with this code:
NSUserDefaults *standard_user_defaults = [NSUserDefaults standardUserDefaults];
if (standard_user_defaults) {
[standard_user_defaults setObject:myString forKey:key];
[standard_user_defaults synchronize];
}
And then, I am getting the value with this code:
NSUserDefaults *standard_user_defaults = [NSUserDefaults standardUserDefaults];
NSString *val = nil;
if (standard_user_defaults)
val = [standard_user_defaults objectForKey:key];
The problem is that if I run this application in my computer is working fine, and I can get the user default value, but if another person runs the application is getting an empty value. Any ideas?
I assume by “another person” you mean another user on your computer. The reason they cannot read what you’ve written to your user defaults is because NSUserDefaults is meant for user-specific values. To save something that your application will be able to access from both your user account and others’, you need to place it in a file stored somewhere in a shared location on the system. One way to do this would be something like this:
NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSLocalDomainMask, YES) objectAtIndex:0];
NSString *filePath = [basePath stringByAppendingPathComponent:#"someFileName"];
// write:
NSDictionary *dataToSave = [NSDictionary dictionaryWithObjectsAndKeys:theValue, #"someKey", nil];
if(filePath && [dataToSave writeToFile:filePath atomically:YES])
{
// success!
}
// read:
NSDictionary *dataToLoad = [NSDictionary dictionaryWithContentsOfFile:filePath];
if(dataToLoad)
{
// success!
NSString *theValue = [dataToLoad objectForKey:#"someKey"];
}
You should try and use valueForKey rather than objectForKey. Looking at your code, there is no reason it shouldn't work for one person and not another.
The one exception would be if you are using the defaults from the settings.bundle. Values stored into settings.bundle for user defaults are not initialized until the user opens the settings page for the first time.

Problems in loading from NSUserDefaults

I have a very strange problem while my app loads from NSUserDefaults.
This is the code in my appDelegate:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *user = [[NSString alloc]initWithString:[defaults objectForKey:#"_settingsUsername"]];
NSString *password = [[NSString alloc]initWithString:[defaults objectForKey:#"_settingsPassword"]];
NSString *instance = [[NSString alloc]initWithString:[defaults objectForKey:#"_settingsInstance"]];
The error is this: [NSPlaceholderString initWithString:]: nil argument'
It's very strange because i put in Settings.bundle -> Root.plist the default values for all the fields above.
Oddly that's how it's supposed to work -- this confused me too initially.
I guess the thing to remember is that you can use NSUserDefaults without the Settings.bundle, so it can't be the only way to set default values.
Apple provide sample code, AppPrefs, that shows how to copy the default value from the settings to NSUserDefaults.
Why don't you just use that?
NSUserDefaults *defaults = [NSUserDefaults standarduserDefaults];
NSString *user = [defaults objectForKey:#"_settingsUsername"];
NSString *password = [defaults objectForKey:#"_settingsPassword"];
NSString *instance = [defaults objectForKey:#"_settingsInstance"];
And make sure that there are objects for these keys.
hope it helps
I think the problem is that if the user hasn't gone into the settings for your app yet then all values returned from NSUserDefaults for those keys are nil. You need to handle that case and act accordingly - probably by going into the Settings.bundle and picking out the default value that you have put in there. I would just write a method that gets the value for a key and if NSUserDefaults returns nil it handles all the querying of the settings bundle for you.

problem with loading from NSUserDefaults, obj-c

I'm having a problem with NSUserDefaults. I'm saving a name, then trying to access it later in the code from another view controller, but it seems that my key is empty or not saved as when I display the string from the key my label is blank.
-(void) saveName {
NSString *name = nameField.text;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:name forKey:#"playersName"];
[defaults synchronize];
}
-(void) viewDidLoad // method called later on in code from different viewcontroller
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *name = [defaults objectForKey:#"playersName"];
playerName.text = name; // player name == myLabel
if ([[NSUsersDefaults standardUserDefaults] objectForKey:#"playersName"] == nil) {
playerName.text =#" blank";
}
}
My string doesn't seem to be saving to userdefaults as the #"blank" string keeps showing up with my label. I'm not too familiar with NSUserDefaults so any help is much appreciated.
A few things to note when using NSUserDefaults:
calls to syncrhonize method is not necesary and will only make it slower if your program is multi threaded.
Check if the key that you use is being used by other libraries in your project
Check if the value that you set to the key is not nil
Try to use stringForKey: or boolForKey: instead of objectForKey:
I had troubles a few times with NSUserDefaults but in the end it's usually my code that's problematic.
I would suggest you to check whether your '(void) saveName' method is being called or not... Put some breakpoint and see the result