Sam Worfell
Sam Worfell

Reputation: 13

Basic Plist help needed within XCode

I am very new to creating applications and haven't fully figured out how to use the plist function within XCode.

My problem is that I have 3 different input methods within a view controller to which the user will select values from, those being a stepper, a picker view and a date that logs the current date, which I would like to save to a plist so that the user can view those entries in a table view within another view controller.

I haven't really used a plist before therefore my question may sound very silly but regardless I need some help with this.

So far I have the inputs setup but they don't really do anything, I know this question is very basic but I am struggling to find information on this that doesn't go too technical.

I can post my code if that will be beneficial.

Any help will be greatly appreciated.

@property (weak, nonatomic) IBOutlet UILabel *balesFedLabel;
@property (weak, nonatomic) IBOutlet UIStepper *balesFedStepper;
@property (weak, nonatomic) IBOutlet UIPickerView *fieldPickerView;
@property (weak, nonatomic) IBOutlet UILabel *dateLabel;
@property (weak, nonatomic) IBOutlet UITextField *sheepGroup;
@property (strong, nonatomic) IBOutlet UIBarButtonItem *backButton;

//Actions
- (IBAction)stepperValueChange:(id)sender;
- (IBAction)saveButton:(id)sender;
- (IBAction)textFieldDoneEditing:(id)sender;


@property NSArray *dataSource;
@property NSString *tempFieldSelection;
@property(nonatomic) UIKeyboardAppearance keyboardAppearanceDark;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self setupArray];

NSLocale *gbLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"];
NSString *dateFormatString = [NSDateFormatter dateFormatFromTemplate:@"dd/MM/yyyy" options:0 locale:gbLocale];

NSLog(@"dataFormatString: %@", dateFormatString);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:dateFormatString];

NSString *stringFromDate = [dateFormatter stringFromDate:[NSDate date]];
self.dateLabel.text = stringFromDate;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {[self.view  endEditing:YES];
}

- (void)setupArray {
_dataSource = [[NSArray alloc] initWithObjects:@"Cow Pasture", @"Top Lot",    @"East Lot", @"West Lot", @"Front Meadow", @"Big Meadow", nil];

}

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [_dataSource count];
}

- (UIView *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row    forComponent:(NSInteger)component {
return [_dataSource objectAtIndex:row];
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
self.tempFieldSelection = [_dataSource objectAtIndex:[pickerView selectedRowInComponent:0]];
}


- (IBAction)stepperValueChange:(id)sender {double baleStepperValue =     self.balesFedStepper.value;
self.balesFedLabel.text = [NSString stringWithFormat:@"%.f", baleStepperValue];
}

- (IBAction)textFieldDoneEditing:(id)sender {[sender resignFirstResponder];
}

- (IBAction)saveButton:(id)sender {
NSLog(@"Bales Fed: %@", self.balesFedLabel.text);
NSLog(@"Sheep Group: %@", self.sheepGroup.text);
NSLog(@"Current Field: %@", self.tempFieldSelection);
NSLog(@"Last Date Fed: %@", self.dateLabel.text);
}

Upvotes: 1

Views: 109

Answers (3)

Juan Catalan
Juan Catalan

Reputation: 2309

Use an NSMutableDictionary and pass it to the destination UIViewController in a property.

For example in your source view controller:

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[@"Bales Fed"] = self.balesFedLabel.text;
dict[@"Sheep Group"] = self.sheepGroup.text;
dict[@"Current Field"] = self.tempFieldSelection;
dict[@"Last Date Fed"] = self.dateLabel.text;

Just pass dict to the destination view controller.

If you want to use a plist these are the two methods available in a NSDictionary class:

- writeToFile:atomically: to write the dictionary to a file (in plist format) and the class method dictionaryWithContentsOfFile: or the instance method initWithContentsOfFile: to retrieve the dictionary from disk.

In your case, to write the dictionary to a file in plist format:

NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"myData.plist"];
[dict writeToFile:filePath atomically:NO];

And in the destination view controller use this code to retrieve the plist from disk:

NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"myData.plist"];
NSDictionary *myData = [NSDictionary dictionaryWithContentsOfFile:filePath];

From Apple's documentation for the first method:

This method recursively validates that all the contained objects are property list objects (instances of NSData, NSDate, NSNumber, NSString, NSArray, or NSDictionary) before writing out the file, and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list.

If the dictionary’s contents are all property list objects, the file written by this method can be used to initialize a new dictionary with the class method dictionaryWithContentsOfFile: or the instance method initWithContentsOfFile:.

I also recommend you to read the guide Property List Programming Guide

Upvotes: 3

Ali Beadle
Ali Beadle

Reputation: 4516

As you are just passing small amounts of user entered data from one view controller to another you do not need to use PLists nor CoreData nor NSUserDefaults. These are all suitable for persistent data but from your description it sounds like it is just transient stuff.

Just store the user data in parameters and then pass them forward to the destination ViewController using the prepareForSegue method. See this SO answer for full details.

Upvotes: 0

LoVo
LoVo

Reputation: 2073

Even when i wouldn`t recommend to use a .plist file here is the code to use it:

NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"YOUR_FILE_NAME" ofType:@"plist"];
NSDictionary *plistDic = [NSDictionary dictionaryWithContentsOfFile:plistPath];

Upvotes: 0

Related Questions