【问题标题】:Basic Plist help needed within XCodeXCode 中需要的基本 Plist 帮助
【发布时间】:2015-05-27 14:40:58
【问题描述】:

我对创建应用程序非常陌生,还没有完全弄清楚如何在 XCode 中使用 plist 函数。

我的问题是,我在视图控制器中有 3 种不同的输入法,用户可以从中选择值,它们是步进器、选择器视图和记录当前日期的日期,我想将其保存到一个 plist,以便用户可以在另一个视图控制器的表视图中查看这些条目。

我之前没有真正使用过 plist,因此我的问题可能听起来很愚蠢,但无论如何我需要一些帮助。

到目前为止,我已经设置了输入,但它们并没有真正做任何事情,我知道这个问题非常基本,但我正在努力寻找不太技术性的信息。

如果有帮助,我可以发布我的代码。

任何帮助将不胜感激。

@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);
}

【问题讨论】:

  • 我不明白第 3 段,您希望来自所有三个来源的数据存储在 plist 中,或者只是最后一个,或者用户选择存储的内容?如果使用 plist 的原因是在视图控制器之间共享,那不一定是正确的选择,但需要更多信息。存储的数据还会改变还是只读?
  • 我希望用户输入的数据都保存在一个plist中,很抱歉不清楚。
  • 基本上用户将使用步进器选择一个整数,然后使用选择器视图选择一个位置,日期是自动的,然后用户将按下保存按钮,所有三位数据都会消失到 plist。
  • 不要使用 plist 来存储您的数据。使用CoreData(如果您已经在项目中使用它)或NSUserDefaults
  • 我不确定其中一些 cmets 来自哪里;我认为没有理由避免将数据存储在提供给应用程序沙箱的适当目录之一的 plist 中。 @SamWorfell 有用的第一步是创建一个包含您要保存的数据的NSDictionary,您这样做了吗,您卡在哪里了? (如果这是您的唯一目标,也不必为了在控制器之间共享数据而将数据持久化到磁盘。)

标签: ios objective-c xcode


【解决方案1】:

使用NSMutableDictionary 并将其传递给属性中的目标UIViewController

例如在您的源视图控制器中:

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;

只需将dict 传递给目标视图控制器。

如果您想使用 plist,以下是 NSDictionary 类中可用的两种方法:

- writeToFile:atomically: 将字典写入文件(plist 格式) 和类方法dictionaryWithContentsOfFile: 或实例方法initWithContentsOfFile: 从磁盘检索字典。

在您的情况下,将字典写入 plist 格式的文件:

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

并在目标视图控制器中使用此代码从磁盘检索 plist:

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

来自 Apple 的第一种方法的文档:

此方法在写出文件之前递归地验证所有包含的对象是属性列表对象(NSDataNSDateNSNumberNSStringNSArrayNSDictionary 的实例),如果所有对象都不是属性列表对象,则返回 NO,因为结果文件不是有效的属性列表。

如果字典的内容都是属性列表对象,则该方法写入的文件可以通过类方法dictionaryWithContentsOfFile:或实例方法initWithContentsOfFile:来初始化一个新字典。

我还建议您阅读指南Property List Programming Guide

【讨论】:

  • 到目前为止,此信息非常有用,我已使用它来增强我的应用程序的其他部分,但它并没有完全解决我的问题,我明天再试一次,当我对此不那么沮丧时,感谢您的贡献。
  • @SamWorfell 如果您需要更多帮助,请告诉我。
  • 所以我决定做的只是针对低年级,这需要我将数据打印到出现在 XCode 控制台中的 NSLog 中,我仍然想将其写入 NSDictionary或 MutableDictionary 但我不太确定该怎么做,我现在想知道我是否可以将 NSLog 打印到文件中,但我目前所拥有的仍然可以让我获得 2:2 并且我可以接受,因为我我只是第一年。感谢您的建议。
  • @SamWorfell 显示 NSLog 输出,以便我为您提供帮助。此外,您在答案中有 4 行代码解释了如何将信息存储在 NSMutableDictionary 中。现在只需将字典保存到文件中即可 - writeToFile:atomically:
  • 2015-05-28 21:24:13.132 FeedDasSheep[1876:38563] 喂入包数:5 2015-05-28 21:24:13.132 FeedDasSheep[1876:38563] 绵羊组:骡子组 1 2015-05-28 21:24:13.132 FeedDasSheep[1876:38563] 当前字段:West Lot 2015-05-28 21:24:13.132 FeedDasSheep[1876:38563] 最后喂食日期:28/05/2015 这是控制台输出来自 NSLog(@"Bales Fed: %@", self.balesFedLabel.text); NSLog(@"羊群:%@", self.sheepGroup.text); NSLog(@"当前字段:%@", self.tempFieldSelection); NSLog(@"Last Date Fed: %@", self.dateLabel.text);
【解决方案2】:

即使我不建议使用 .plist 文件,这里也是使用它的代码:

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

【讨论】:

    【解决方案3】:

    由于您只是将少量用户输入的数据从一个视图控制器传递到另一个视图控制器,因此您不需要使用 PLists、CoreData 或 NSUserDefaults。这些都适用于持久数据,但从您的描述来看,这听起来只是暂时的东西。

    只需将用户数据存储在参数中,然后使用 prepareForSegue 方法将它们转发到目标 ViewController。详情请参阅this SO answer

    【讨论】:

      猜你喜欢
      • 2011-04-03
      • 2011-05-20
      • 2012-10-10
      • 1970-01-01
      • 1970-01-01
      • 2011-11-22
      • 1970-01-01
      • 2013-07-22
      • 1970-01-01
      相关资源
      最近更新 更多