前面我们已经创建了一个简单的表视图应用程序,显示菜谱列表。分析一下代码,你会发现所有的菜谱都应编码在源代码中。之前,我们只考虑让事情变得简单,并着重演示如何创建一个 UITableView 应用程序。然而,将所有元素比硬编码在
代码中并不是推荐的方法。
在真实的App开发中,我们常常将这些静态元素存放在外部(如菜谱列表)文件或数据库或其它地方。在IOS编程中,有一种类型的文件,成为 Property List. 这一类型的文件通常在Mac OS 和 iOS中发现,用来存放简单的结构数据(如应用程序设置)。
下面,我们来更新之前的Simple Table 应用程序,使用 Property List.
我们将讨论如下一些主题:
1)转化静态数组中的表数据为 Property List
2)如何读取 Property List
1.为什么外部化表数据?
将静态数据从代码分离出来是一个很好的做法。为什么呢? 将表数据置于外部数据源的优点是什么呢?
假如让你添加50多个菜谱到Simple Table 应用程序中,你需要返回源代码,将新的菜谱添加到初始化代码中。
这种做法并没有任何问题,但是,编写这些代码并不简单,必须要严格遵循Object-C语法。更改代码可能会引起其他错误,这并不是我们期望的。
显然,最好是将数据和代码逻辑分离,像下面这一将表数据存放起来不是更好吗?
实际上,可能并不是你提供表数据(本例子是菜谱列表数据),而是其他不懂iOS编程经验的人提供这些数据。当我们将数据放置在外部文件,这样容易读写,且更容易理解。
随着更深入学习,我们将了解如何将数据存放在Server端(或者所谓的云)
App中所有数据将根据需要从Server端读取。目前,这一提供了很大的好处,因为对数据的任何更新都需要你重构App,并提交给App审批。通过将数据分离存放在云(Cloud)中,你可以随时更新数据,而不是更新你的App。
现在,我们来看看如何使用Property List.
2. Property List 是什么?
Property List 提供了一个方便的方法来存放简单的结构数据,通常为XML格式。
你不能使用Property List存放所有类型的数据,Property List中存放的数据类型是有限的,包括数组(Array)、字典(Dictionary)、字符串(String)等等。 关于支持类型的更详细信息,可参考Property List文档。
3.这是存放表数据的最好方式吗?
不是,绝对不是,我们使用Property List 来演示如何在外部文件存放表数据,这仅仅是一个例子。
4.转换表数据为Property List
首先,右击SimpleTable 文件夹,选择New File..., 接着选择iOS模板下面的Resource,最后选择Property List, 并点击next继续。
在弹出窗口中,使用recipes 作为文件名。确认之后,Xcode将自动创建Property List文件。
我们需要在PropertyList 中添加3个数组数据,我们在Property List中添加3行,类型为Array。分别命名Key值为:
RecipeName,Thumbnail和PrepTime.
Key值作为识别码,在后面的代码中用来获取相应的数组。
点击展开图标,并点击 + 图标,添加新的 item ,实现数组中添加数据。完成后的Property List 如下图所示:
附件提供recipes.plist 文件下载
5.在Object-C中加载Property List
接着,我们更新代码,从上一步创建的Property List文件中加载菜谱列表,从Property List中读取内容相当简单。 iOS SDK已经有内置的方法来处理该文件的读取操作。
替换代码如下:
//Find out the path of recipes.plist
NSString *path = [[ NSBundle mainBundle ] pathForResource : @"recipes" ofType : @"plist" ];
//Load the file content and read the data into arrays
NSDictionary *dict = [[ NSDictionary alloc ] initWithContentsOfFile :path];
tableData = [dict objectForKey : @"RecipeName" ];
thumbnails = [dict objectForKey : @"Thumbnail" ];
time = [dict objectForKey : @"PrepTime" ];
//Initialize prepTime
prepTime = @"PrepTime:" ;