使用NSKeyedArchiver持久化数据(Swift 3)

Apple提供了两种在应用程序启动之间保留数据的方法:Core Data和NSKeyedArchiver。

NSKeyedArchiver编码(保存)和解码(检索)您要持久保存的所有与NSCoding兼容的类。 尽管NSKeyedArchiver不如Core Data健壮(它速度较慢且手动),但它可以完成所需的持久化数据工作,并且不如Core Data复杂。

NSCoding是一种协议,它需要两种方法- 必需的init(编码器解码器:NSCoder)encode(使用编码器:NSCoder) 。 如果我创建一个符合NSObject和NSCoder的类,则可以将该类序列化(从其当前数据结构转换为可以存储为字节的格式),并反序列化(从字节提取为数据结构)为可以保存到用户磁盘。

为了演示,我将创建一个购物清单应用程序。

步骤1:在情节提要中创建一些UI。

对于此应用程序,我使用了标签栏控制器。 第一个选项卡Add New Item包含一个标签,一个textField和一个按钮。 第二个选项卡Shopping Shopping只是一个tableView,显示了第一个选项卡中我添加的项目。

步骤2:创建我的模型对象和一个单例对象作为我的共享DataStore。

我的对象将是ShoppingItems,现在,每个ShoppingItem都有一个属性:name。

我创建了一个名为ShoppingList的类,并采用了NSObject和NSCoding协议,这将使该类与NSKeyedArchiver兼容。

我创建了1)我的ShoppingList的name属性,2)我的ShoppingList的初始化程序,以及3)创建了一个结构,该结构包含一个静态名称属性来保存我的NSCoding键(为安全起见)。

NSCoder需要两种方法,解码所需的init和编码器进行编码。 encode(使用coder:NSCoder)方法将保存(编码)我创建的Key.name的name属性。 所需的init(coder encoder:NSCoder)方法将检索我保存的名称对象并将其转换为字符串。

我还为我的name属性创建了一个getter / setter,以确保使用加载的newValue更新它。

我还使用单例作为“数据存储”,以便在我的shoppingList数组中拥有一个位置。

步骤3:为我的文本框和按钮创建一个插座和操作。

这些是必需的,以便在单击按钮后我可以在textField中检索输入的文本,并将该文本另存为新的shoppingItem。

第4步:创建一个代表filePath的变量,该变量将指定我们应在何处保存此数据。

在具有textField和按钮的viewController中,创建一个filePath属性。 此filePath属性应创建一个FileManager (如手机上的文件柜文件和文件夹)。 它还应该在我们documentDirectory中 FileManager的url数组中检索一个url。 在这里,我检索了第一个filePath。 filePath属性应该返回该URL,并附加您指定的路径,我使用了“数据”。

  var filePath:字符串{ 
  // 1-管理员可让您检查应用程序中文件和文件夹的内容; 创建一个目录到我们要保存的目录 
 让经理= FileManager.default 
  // 2-这从我们的documentDirectory返回一个url数组,我们采用第一个路径 
 让url = manager.urls(for:.documentDirectory,in:.userDomainMask).first 
  print(“这是documentDirectory \(url)中的url路径”) 
  // 3-创建一个新的路径组件,并创建一个名为“ Data”的新文件,该文件将存储我们的Data数组。 
 返回(url!.appendingPathComponent(“ Data”)。path) 
  } 

步骤5:编写将这些数据保存到用户电话的功能。

我编写了一个私有函数来保存我的shoppingItem,方法是:1)将其追加到我的DataStore单例中的shoppingItems数组中。2)使用NSKeyedArchiver将此shopItems数组归档到我的指定文件路径中。

 私人功能saveData(item:ShoppingItem){ 
  self.store.shoppingItems.append(项目) 
  // 4-NSKeyedArchiver将在每个购物清单类中寻找并寻找编码功能,并将对我们的数据进行编码并将其保存到我们的文件路径中。 这完成了编码和解码的所有工作。 
  // 5-归档根对象将我们的购物商品(我们的数据)数组保存到文件路径url 
  NSKeyedArchiver.archiveRootObject(self.store.shoppingItems,toFile:filePath) 
  } 

NSKeyedArchiver显式调用我在shoppingList模型中编写的编码和解码函数。 archiveRootObject函数会将其保存到我们之前声明的文件路径中。

第6步:编写一个函数,将加载我们保存的数据。

保存数据后,我们希望能够在关闭应用程序并重新打开之后检索数据。

为此,我们解包NSKeyedArchiver并调用unarchiveObject方法,该方法会将我们的数据反序列化为所需的ShoppingItem数组。 然后,我们可以获取此加载的数据,并将其分配回单例中的shoppingItems数组。

 私人func loadData(){ 
  // 6-如果我们可以从存档中取回数据(加载数据),请沿着文件路径获取数据并将其转换为ShoppingItems数组 
 如果让ourData = NSKeyedUnarchiver.unarchiveObject(withFile:filePath)作为?  [ShoppingItem] { 
  self.store.shoppingItems = ourData 
  } 
  } 

第7步:运行该应用程序,添加一些shoppingList项目,停止该应用程序,在模拟器中关闭该应用程序,然后再次打开该应用程序以查看我的商品是否仍然存在。

我期待着将来使用它来保留我的一些应用程序数据!

在下面发表评论,让我知道您是否有帮助。

您可以在这里找到我的仓库。

资源:

NSHipster-NSCoding: http ://nshipster.com/nscoding/

Apple文档-NSKeyedArchiver: https : //developer.apple.com/reference/foundation/nskeyedarchiver