从 swift 2 中的 plist 读取时无法创建 NSDictionary

Posted

技术标签:

【中文标题】从 swift 2 中的 plist 读取时无法创建 NSDictionary【英文标题】:Failed to create NSDictionary when reading from plist in swift 2 【发布时间】:2016-02-15 14:18:24 【问题描述】:

我正在尝试从 plist (PetList.plist) 中读取信息,但我不知道为什么它失败了。变量路径是正确的,但是 myDict 为 nil,else 部分被执行。我想要做的是加载信息表单 plist,然后将值分配给宠物数组。 var pets = 宠物 func loadGameData()

    let path = NSBundle.mainBundle().pathForResource("PetList", ofType: "plist")

    let myDict = NSDictionary(contentsOfFile: path!)

    if let dict = myDict 
        //loading values
        for i in 0..<pets.count 
            pets[i].petName = dict.objectForKey("petName")!.absoluteString!
            pets[i].health = dict.objectForKey("health")!.absoluteString!
            pets[i].experience = dict.objectForKey("experience")!.absoluteString!
            pets[i].hungry = dict.objectForKey("hungry")!.absoluteString!
            pets[i].energy = dict.objectForKey("energy")!.absoluteString!
            pets[i].level = dict.objectForKey("level")!.absoluteString!
            pets[i].status = dict.objectForKey("status")!.absoluteString!
            pets[i].searchKey = dict.objectForKey("searchKey")!.absoluteString!
            pets[i].cleanliness = dict.objectForKey("cleanliness")!.absoluteString!
            pets[i].isChoosed = dict.objectForKey("isChoosed")!.absoluteString!
            pets[i].skill = dict.objectForKey("skill")!.absoluteString!
            pets[i].imageName = dict.objectForKey("imageName")!.absoluteString!
        
     else 
        print("WARNING: Couldn't create dictionary from PetList.plist! Default values will be used!")
    

【问题讨论】:

PetList.plist 实际上在 app bundle 中? 字典中的所有值都是NSURL 对象还是absoluteString 的用途?除此之外,您正在创建具有相同内容的 pets.count 对象。集合类型之一必须是数组。 是的,@***fo 这是我打印的路径。 /Users/Neo/Library/Developer/CoreSimulator/Devices/1276FC11-668D-4CAC-87AE-C61141DD00E4/data/Containers/Bundle/Application/06DEB9B7-B58F-417C-8232-3F3796630F80/CandyPets.app/PetList.plist跨度> @vadian absoluteString 用于获取字符串。但 myDict 为 nil,它们不会运行。 absoluteStringNSURL 类的属性,用于获取符合 RFC 1808 的 URL 字符串表示。打印出myDict,我怀疑不是字典 【参考方案1】:

有一些问题。

顶层对象是一个数组 absoluteString 会导致编译器错误。 必须有 Pet 结构或类才能从数组创建实例。

类似的东西

struct Pet 
  var petName = "", health = "", experience = "", hungry = ""
  var energy = "", level = "", status = "", searchKey = ""
  var cleanliness = "", isChoosed = "", skill = "", imageName = ""


var pets = [Pet]()

func loadGameData() 

  let path = NSBundle.mainBundle().pathForResource("PetList", ofType: "plist")
  if let myArray =  NSArray(contentsOfFile: path!) as? [[String:String]] 
    //loading values

    for anItem in myArray 
      var pet = Pet()
      pet.petName = anItem["petName"]!
      pet.health = anItem["health"]!
      pet.experience = anItem["experience"]!
      pet.hungry = anItem["hungry"]!
      pet.energy = anItem["energy"]!
      pet.level = anItem["level"]!
      pet.status = anItem["status"]!
      pet.searchKey = anItem["searchKey"]!
      pet.cleanliness = anItem["cleanliness"]!
      pet.isChoosed = anItem["isChoosed"]!
      pet.skill = anItem["skill"]!
      pet.imageName = anItem["imageName"]!
      pets.append(pet)
    
   else 
    print("WARNING: Couldn't create array from PetList.plist! Default values will be used!")
  

【讨论】:

你真好!谢谢! 我在尝试写入 plist 时遇到了一个新问题。 fileManager.fileExistsAtPath(path) 返回 false。 ios 中,您无法写入应用程序包。使用Documents 目录 另外,我建议Pet 类实现一个初始化器,命名方式为:init(withDictionary dictionary:[String : String]),这样只有Pet 类知道字典格式的内部结构。所以for 循环变为:for anItem in myArray var pet = Pet(withDictionary:anItem); pets.append(pet) @NicolasMiari 当然,代码只是一个基本示例。【参考方案2】:

PetList.plist 的***节点是一个数组,而不是字典,这就是它没有加载的原因。

【讨论】:

以上是关于从 swift 2 中的 plist 读取时无法创建 NSDictionary的主要内容,如果未能解决你的问题,请参考以下文章

从 plist 错误 Swift 加载

如何在 swift 中读取数组和字典的 plist

Swift:从 MainBundle 读取 plist 并直接写入 Documents 失败

swift 3.1 从 web 读取 CSV 或 PLIST 文件

Swift 3:无法将数据写入 plist 文件

使用 Swift,从 plist 加载数据时,如何区分布尔值和整数值?