在Swift中将数组保存到文件

3

我正在开发一个应用程序,它将会:

  1. 检查互联网连接;
  2. 从服务器接收JSON文件,并在可访问的情况下将数据存储在文件中;
  3. 如果无法连接到服务器,则从文件中读取。

现在,我已经成功实现了连接检查、接收JSON和将数据放入数组的功能。

接收到的JSON文件的格式如下:

enter image description here

然后我使用以下代码创建一个字典数组来存储JSON数据。选择字典数组是为了能够对其进行过滤,然后使用值的键来访问值。

var rates = [ExchangeRates]()  //instance of class Rate
var bnkDct  =  ["bank": "", "currency": "","buyrate": "", "sellrate": ""] //template
var indx : Int = 0 //index for iteration

            for rate in jsonData{
                let rate = ExchangeRates(data: rate as! NSDictionary)

                rates.append(rate)

                    bnkDct["bank"] = rates[indx].bank
                    bnkDct["buyrate"] = rates[indx].buyRate
                    bnkDct["sellrate"] = rates[indx].sellRate
                    bnkDct["currency"] = rates[indx].currency

                self.bankDict.append(bnkDct)
                indx += 1
            }

在此之后,我有一个看起来像这样的数组:

enter image description here

现在我想将这个数组保存到文件中,并且显然要能够读取它。
我尝试使用类似于以下代码来编写数据:
        let filePath = NSTemporaryDirectory() + "MyData.dat"

        self.bankDict.writeToFile(filePath, automatically: true)

但是它给了我一个错误:"[(Dictionary)] doesn't have writeToFile member"。
而且我无法将其转换为NSDictionary来使用相同的writeToFile方法。
另外,我试图使用以下方式写入数据:
        let filePath = NSTemporaryDirectory() + "MyData.dat"

        NSKeyedArchiver.archiveRootObject(self.bankDict, toFile: filePath)

它创建了一个具有奇怪编码的文件:

enter image description here

当我尝试阅读它时:

 let newDictionary = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as! [Dictionary <String,AnyObject> ]

我收到了这个错误提示:"fatal error: unexpectedly found nil while unwrapping an Optional value"。

同时,调试器显示了一个非常"有趣"的东西:

enter image description here

newDictionary变量有无数个值。在文件中编写的数组中有40个字典。

有人能给我建议吗?我在这里做错了什么,或者我在做某些事情时使用了不好的实践?


移除类型转换 as! [Dictionary <String,AnyObject> ],然后查看该值是什么。 - Adam
我的猜测是,你在应用程序启动之间丢失了保存的文件,因为NSTemporaryDirectory路径每次应用程序启动时都会发生变化。解决方法是将其保存到永久位置。至于newDictionary和它的无数项,这只是调试器因为在变量声明之后但在填充之前停止时找不到实际变量内容而感到困惑。我敢打赌这个变量实际上是空的。 - Eric Aya
@EricD. 谢谢回复,但似乎它能够很好地找到文件。我正在使用以下函数: func getFileURL(fileName: String) -> NSURL { let manager = NSFileManager.defaultManager() let dirURL = manager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false, error: nil) return dirURL!.URLByAppendingPathComponent(fileName) }let filePath = getFileURL("MyData.dat").path!我尝试比较文件路径,它们是匹配的。 - Almazini
@Adam 当我移除类型转换时,它会显示警告。如果我运行应用程序,它将使用 AnyObject? 类型,并且值为 nil。 - Almazini
考虑到一个[String:String]的数组可以写入一个属性列表文件,该文件的扩展名为plist - vadian
显示剩余6条评论
1个回答

5

如果您的对象图中包含非属性列表对象,则无法使用数组或字典的writeToFile方法。(这里有一个小型类型列表,可以查阅一下。)

在您的数组中有一个自定义类 ExchangeRates。

同样地,如果您的对象图中的每个对象都符合NSCoding协议,才能使用NSKeyedArchiver保存文件。如果您在ExchangeRates类中添加了对NSCoding的支持,则第二种方法将会生效,但是文件内容将无法被人类读取。


你能解释一下我应该如何使用NSCoding吗? - Almazini
完美的链接介绍了NSCoding。感谢您添加这个。 - Duncan C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接