2016-08-22 50 views
0

解析JSON我遇到问题,当我使用nil合并来尝试并返回一个有时不存在的键/值集合的默认值时。我解析json的网站是http://heroesjson.com。创作者甚至给我一张如何解析它的地图。我遇到问题的时候是我试图解析人才的关键。并非每个人才都有“冷却时间”或“先决条件”的关键。所以我尝试使用nil合并来分配一个默认值,如果键/值集合不存在,但当我尝试将值分配给iCooldown或sPrerequisite时,我会在尝试展开可选参数时意外发现错误nil。自从我给它一个默认值以后,这怎么可能?无解析JSON时合并返回nil而不是默认值

//Parse Talent Class 
         if let talentsArray = dict[x]["talents"] as? Dictionary<String, AnyObject> { 

          for y in 0 ..< dict.count { 
           if let allHeroTalents = talentsArray["\(y)"]{ 
            for z in 0 ..< allHeroTalents.count { 


              let id = allHeroTalents[z]["id"] 
              let name = allHeroTalents[z]["name"] 
              let description = allHeroTalents[z]["description"] 
              let cooldown = allHeroTalents[z]["cooldown"] ?? 0.0 
              let prerequisite = allHeroTalents[z]["prerequisite"] ?? "" 
              let icon = allHeroTalents[z]["icon"] 


              let sId = id as? String 
              let sName = name as? String 
              let sDescription = description as? String 
              //let iCooldown = cooldown as! Double 
              //let sPrerequisite = prerequisite as! String 
              let sIcon = icon as? String 
              //let talent = Talent(id: sId!, name: sName!, description: sDescription!, cooldown: iCooldown, prerequisite: sPrerequisite, icon: sIcon!) 
             print("\(hero.name) has talent \(cooldown)") 


            } 
           } 
          } 

         } 

我已将下面的整个文件包括在内以供参考。我的主文件只是调用func parseData()。

import Foundation 
 

 

 

 
class Hero { 
 

 
    var id: String? 
 
    var attributeid: String? 
 
    var name: String? 
 
    var title: String? 
 
    var description: String? 
 
    var role: String? 
 
    var type: String? 
 
    var gender: String? 
 
    var franchise: String? 
 
    var difficulty: String? 
 
    var icon: String? 
 
    var ratings: Ratings? 
 
    var stats: Stats? 
 
    var talents: [Talent]? 
 
    
 
    
 
    
 
    
 
    
 
    init(id: String, attributeid: String, name: String, title: String, description: String, role: String, type: String, gender: String, franchise: String, difficulty: String, icon: String){ 
 
     self.id = id 
 
     self.attributeid = attributeid 
 
     self.name = name 
 
     self.title = title 
 
     self.description = description 
 
     self.role = role 
 
     self.type = type 
 
     self.gender = gender 
 
     self.franchise = franchise 
 
     self.difficulty = difficulty 
 
     self.icon = icon 
 

 
     
 
    } 
 
    
 
} 
 

 

 
class Ratings { 
 
    var damage: Int? 
 
    var utility: Int? 
 
    var survivability: Int? 
 
    var complexity: Int? 
 
    
 
    
 
    init(damage: Int, utility: Int, survivability: Int, complexity: Int) { 
 
     self.damage = damage 
 
     self.utility = utility 
 
     self.survivability = survivability 
 
     self.complexity = complexity 
 
    } 
 
} 
 

 
class Stats { 
 
    var hp: Int? 
 
    var hpPerLevel: Int? 
 
    var hpRegen: Double? 
 
    var hpRegenPerLevel: Double? 
 
    var mana: Int? 
 
    var manaPerLevel: Int? 
 
    var manaRegen: Double? 
 
    var manaRegenPerLevel: Double? 
 
    
 
    
 
    init(hp: Int, hpPerLevel: Int, hpRegen: Double, hpRegenPerLevel: Double, mana: Int, manaPerLevel: Int, manaRegen: Double, manaRegenPerLevel: Double) { 
 
     self.hp = hp 
 
     self.hpPerLevel = hpPerLevel 
 
     self.hpRegen = hpRegen 
 
     self.hpRegenPerLevel = hpRegenPerLevel 
 
     self.mana = mana 
 
     self.manaPerLevel = manaPerLevel 
 
     self.manaRegen = manaRegen 
 
     self.manaRegenPerLevel = manaRegenPerLevel 
 
    } 
 
    
 
    
 
} 
 

 
class Talent { 
 
    var id: String? 
 
    var name: String? 
 
    var description: String? 
 
    var cooldown: Double? 
 
    var prerequisite: String? 
 
    var icon: String? 
 
    
 

 
    
 
    init(id: String, name: String, description: String, cooldown: Double, prerequisite: String, icon: String) { 
 
     self.id = id 
 
     self.name = name 
 
     self.description = description 
 
     self.cooldown = cooldown 
 
     self.prerequisite = prerequisite 
 
     self.icon = icon 
 
     
 
    } 
 
    
 
    
 
} 
 

 
class Ability { 
 
    var id: String? 
 
    var name: String? 
 
    var description: String? 
 
    var shortcut: String? 
 
    var cooldown: Double? 
 
    var manaCost: Double? 
 
    var manaCostPerSecond: Double? 
 
    var aimType: String? 
 
    var heroic: Bool? 
 
    var trait: Bool? 
 
    var mount: Bool? 
 
    var icon: String? 
 
    
 
    init(id: String, name: String, description: String, shortcut: String, cooldown: Double, manaCost: Double, manaCostPerSecond: Double, aimType: String, heroic: Bool, trait: Bool, mount: Bool, icon: String){ 
 
     self.id = id 
 
     self.name = name 
 
     self.description = description 
 
     self.shortcut = shortcut 
 
     self.cooldown = cooldown 
 
     self.manaCost = manaCost 
 
     self.manaCostPerSecond = manaCostPerSecond 
 
     self.aimType = aimType 
 
     self.heroic = heroic 
 
     self.trait = trait 
 
     self.mount = mount 
 
     self.icon = icon 
 

 
    } 
 
    
 
} 
 

 
func parseData(){ 
 
    let urlString = "http://heroesjson.com/heroes.json" 
 
    let session = NSURLSession.sharedSession() 
 
    let url = NSURL(string: urlString)! 
 
    
 
    session.dataTaskWithURL(url) { (data: NSData?, response:NSURLResponse?, error: NSError?) -> Void in 
 
     
 
     if let responseData = data { 
 
      
 
      do { 
 
       let json = try NSJSONSerialization.JSONObjectWithData(responseData, options: NSJSONReadingOptions.AllowFragments) 
 
       
 
       if let dict = json as? [Dictionary<String, AnyObject>] { 
 

 
        for x in 0 ..< dict.count { 
 
         
 
         
 
         if let id = dict[x]["id"], let attributeid = dict[x]["attributeid"], let name = dict[x]["name"], let title = dict[x]["title"], let description = dict[x]["description"], let role = dict[x]["role"], let type = dict[x]["type"], let gender = dict[x]["gender"], let franchise = dict[x]["franchise"], let difficulty = dict[x]["difficulty"], let icon = dict[x]["icon"] { 
 
          
 
          let hero = Hero(id: id as! String, attributeid: attributeid as! String, name: name as! String, title: title as! String, description: description as! String, role: role as! String, type: type as! String, gender: gender as! String, franchise: franchise as! String, difficulty: difficulty as! String, icon: icon as! String) 
 
          
 
          // Parse Ratings Class 
 
          
 
          if let dataArray = dict[x]["ratings"] as? Dictionary<String, Int> { 
 
           
 
           if let damage = dataArray["damage"], let utility = dataArray["utility"], let survivability = dataArray["damage"], let complexity = dataArray["complexity"] { 
 
            
 
            let rating = Ratings(damage: damage , utility: utility , survivability: survivability , complexity: complexity) 
 
            hero.ratings = rating 
 
            //print("\(hero.name) has a damage rating of \(hero.ratings!.damage)") 
 
            
 
           } 
 
          } 
 
          
 
          //Parse Stats Class 
 
          if let statsArray = dict[x]["stats"] as? Dictionary<String, AnyObject> { 
 
           
 

 
           if let dummy = statsArray[hero.id!]{//error handleing for vikings 
 
            
 
            
 
            if let hp = statsArray[hero.id!]!["hp"], let hpPerLevel = statsArray[hero.id!]!["hpPerLevel"], let hpRegen = statsArray[hero.id!]!["hpRegen"], let hpRegenPerLevel = statsArray[hero.id!]!["hpRegenPerLevel"], let mana = statsArray[hero.id!]!["mana"], let manaPerLevel = statsArray[hero.id!]!["manaPerLevel"], let manaRegen = statsArray[hero.id!]!["manaRegen"], let manaRegenPerLevel = statsArray[hero.id!]!["manaRegenPerLevel"] { 
 
             
 
             
 
             let stats = Stats(hp: hp as! Int, hpPerLevel: hpPerLevel as! Int, hpRegen: hpRegen as! Double, hpRegenPerLevel: hpRegenPerLevel as! Double, mana: mana as! Int, manaPerLevel: manaPerLevel as! Int, manaRegen: manaRegen as! Double, manaRegenPerLevel: manaRegenPerLevel as! Double) 
 
             
 
             
 
             hero.stats = stats 
 
            } 
 
            
 
           }//closes let dummy 
 
           
 
           
 
          } 
 
          
 
          //Parse Talent Class 
 
          if let talentsArray = dict[x]["talents"] as? Dictionary<String, AnyObject> { 
 
           
 
           for y in 0 ..< dict.count { 
 
            if let allHeroTalents = talentsArray["\(y)"]{ 
 
             for z in 0 ..< allHeroTalents.count { 
 

 
              
 
               let id = allHeroTalents[z]["id"] 
 
               let name = allHeroTalents[z]["name"] 
 
               let description = allHeroTalents[z]["description"] 
 
               let cooldown = allHeroTalents[z]["cooldown"] ?? 0.0 
 
               let prerequisite = allHeroTalents[z]["prerequisite"] ?? "" 
 
               let icon = allHeroTalents[z]["icon"] 
 
              
 
              
 
               let sId = id as? String 
 
               let sName = name as? String 
 
               let sDescription = description as? String 
 
               //let iCooldown = cooldown as! Double 
 
               //let sPrerequisite = prerequisite as! String 
 
               let sIcon = icon as? String 
 
               //let talent = Talent(id: sId!, name: sName!, description: sDescription!, cooldown: iCooldown, prerequisite: sPrerequisite, icon: sIcon!) 
 
              print("\(hero.name) has talent \(cooldown)") 
 
              
 
              
 
             } 
 
            } 
 
           } 
 
           
 
          } 
 
          
 
          // Parse Ability Class 
 

 
          if let abilitiesArray = dict[x]["abilities"] as? Dictionary<String, AnyObject> { 
 
           for c in 0 ..< abilitiesArray.count { 
 
            
 
            for d in 0 ..< abilitiesArray.count { 
 
             
 
            if let dummy = abilitiesArray[hero.id!]{ 
 
             
 
              
 
              let id = abilitiesArray[hero.id!]!["id"] 
 
              let name = abilitiesArray[hero.id!]!["name"] 
 
              let description = abilitiesArray[hero.id!]!["description"] 
 
              let shortcut = abilitiesArray[hero.id!]!["shortcut"] 
 
              let cooldown = abilitiesArray[hero.id!]!["cooldown"] 
 
              let manaCost = abilitiesArray[hero.id!]!["manaCost"] 
 
              let manaCostPerSecond = abilitiesArray[hero.id!]!["manaCostPerSecond"] 
 
              let aimType = abilitiesArray[hero.id!]!["aimType"] 
 
              let heroic = abilitiesArray[hero.id!]!["heroic"] 
 
              let trait = abilitiesArray[hero.id!]!["trait"] 
 
              let mount = abilitiesArray[hero.id!]!["mount"] 
 
              let icon = abilitiesArray[hero.id!]!["icon"] 
 

 
              
 
              let sId = id as? String 
 
              let sName = name as? String 
 
              let sDescription = description as? String 
 
              let sShortcut = shortcut as? String 
 
              let sCooldown = cooldown as? Double 
 
              let sManaCost = manaCost as? Double 
 
              let sManaCostPerSecond = manaCostPerSecond as? Double 
 
              let sAimType = aimType as? String 
 
              let sHeroic = heroic as? Bool 
 
              let sTrait = trait as? Bool 
 
              let sMount = mount as? Bool 
 
              let sIcon = icon as? String 
 
              
 
              
 
//           let abilities = Ability(id: sId!, name: sName!, description: sDescription!, shortcut: sShortcut!, cooldown: sCooldown!, manaCost: sManaCost!, manaCostPerSecond: sManaCostPerSecond!, aimType: sAimType!, heroic: sHeroic!, trait: sTrait!, mount: sMount!, icon: sIcon!) 
 
             
 
             
 
             
 
            } 
 
           } 
 
           
 
           } 
 
           
 
           
 
           
 
           
 
          } 
 
          
 
          
 
          heroes.append(hero) 
 
         } 
 
        } 
 
       } 
 
      } catch { 
 
       print("Could not serialize") 
 
      } 
 
     } 
 
     
 
     
 
     }.resume() 
 
    
 
    
 
    
 
    
 
}

+1

我建议几件事情:你的解析数据功能越来越漂亮矮胖。我会建议提取'Dictionary'以将对象转换为初始化。例如,赋予'Ability'一个采用'[String:Any]'参数的初始化器,并自动为其分配适当的成员。这也使得更改这些数据类变得更容易,因为您可以添加一个成员,并将其赋值添加到初始化程序中,而无需绕过parseData和其他函数 – Alexander

+0

此外,您的所有类成员都是可选的,var '变量。他们中的很多人看起来像他们可以是非可选和'let'常量。 – Alexander

+0

@AlexanderMomchliov你可以给我一个例子,说明我会怎么做(给一个初始化器带一个[String:Any]参数,并自动分配成员)?我是新来的编码,甚至不知道这是可能的。 – Apple

回答

3

我可能是错的,但似乎你正在使用你的词典为Array。这会导致您打开不存在的可选值。

从代码:

//- talentsArray is a dictionary! 
if let talentsArray = dict[x]["talents"] as? Dictionary<String, AnyObject> { 
    for y in 0 ..< dict.count { 
     //- talentsArray["\(y)"] y is a value from 0 to the count, not necesarilly a key. 
     if let allHeroTalents = talentsArray["\(y)"]{ 
      for z in 0 ..< allHeroTalents.count { 
       // ... 
      } 
     } 
    } 
} 

字典没有维持秩序,如果你需要通过他们迭代,你可以列举你的字典,你必须使用for (key, value) in dictionary语法。沿着线的东西:

if let talents = dict[x]["talents"] as? Dictionary<String, AnyObject> { 
    for (index, talent) in talents { 
     for attribute in talent { 
      // Do your thing. 
     } 
    } 
} 

你的问题,我的理解,是不是聚结,但不正确使用字典DS的。我复制的API调用,可以看到,即使你在哪里遍历它,同时把指数作为字典的键,你会碰到一些麻烦,因为键是没有办法的顺序:

enter image description here

UPDATE

正如我在评论中所提到的,而你的解决方案的工作let cooldown = item[cooldown]!将迫使解开你的选购,这是不符合获取从API(可选值特别打交道时,如果他们并不总是最好的方法包括在您提到的原始问题中的数据中)。假设你的“冷却”是一张双人床和“先决条件”是一个字符串,我会实现它是这样的:

let cooldown = item["cooldown"] as? Double ?? 0.00 
let prerequisite = item["prerequisite"] as? String ?? "" 

这种方法将解开你的选购,同时铸造到正确的预期的类型,然后合并的价值的关键值对。这种方法更安全,因为它不会假定API调用将包含这些密钥。

希望这会有所帮助!

+0

如果你只是在寻找一个特定的键,你应该添加一个关于不需要遍历字典的部分 – Alexander

+0

虽然这确实帮助我更容易地访问我的数据,但它并没有解决我的问题。我确实实施了你的建议,他们确实有帮助。零合并操作员需要一个!并修复了一切。让prerequisite = item [“先决条件”]! ?? “”。 – Apple

+1

你好,我很高兴它帮助,但我想建议,然而解开你的可选的力量不是一个好主意,你明白为什么现在工作?当你访问你的字典的成员,即'让冷却=物品[冷却]!“你快速告诉你,你100%确定你的字典包含一个拥有关键'冷却时间'的成员。但是,如果Api发生变化会发生什么?或者如果你得到的英雄没有那个成员?你的应用程序将失败,你会得到一个'发现零,同时解开你的可选',这打破了零合并的目的。 –

-1

我偶然发现了我的代码。显然,我所需要做的就是解包(使用!)变量进入零合并操作符。

let cooldown = item["cooldown"]! ?? 0.00 
let prerequisite = item["prerequisite"]! ?? "" 

整个工作守则

import Foundation 
 

 

 

 
class Hero { 
 

 
    var id: String? 
 
    var attributeid: String? 
 
    var name: String? 
 
    var title: String? 
 
    var description: String? 
 
    var role: String? 
 
    var type: String? 
 
    var gender: String? 
 
    var franchise: String? 
 
    var difficulty: String? 
 
    var icon: String? 
 
    var ratings: Ratings? 
 
    var stats: Stats? 
 
    var talents: [String: [Talent]]? 
 
    var abilities: [String: [Ability]]? 
 
    
 
    
 
    
 
    
 
    
 
    init(id: String, attributeid: String, name: String, title: String, description: String, role: String, type: String, gender: String, franchise: String, difficulty: String, icon: String){ 
 
     self.id = id 
 
     self.attributeid = attributeid 
 
     self.name = name 
 
     self.title = title 
 
     self.description = description 
 
     self.role = role 
 
     self.type = type 
 
     self.gender = gender 
 
     self.franchise = franchise 
 
     self.difficulty = difficulty 
 
     self.icon = icon 
 

 
     
 
    } 
 
    
 
} 
 

 

 
class Ratings { 
 
    var damage: Int? 
 
    var utility: Int? 
 
    var survivability: Int? 
 
    var complexity: Int? 
 
    
 
    
 
    init(damage: Int, utility: Int, survivability: Int, complexity: Int) { 
 
     self.damage = damage 
 
     self.utility = utility 
 
     self.survivability = survivability 
 
     self.complexity = complexity 
 
    } 
 
} 
 

 
class Stats { 
 
    var hp: Int? 
 
    var hpPerLevel: Int? 
 
    var hpRegen: Double? 
 
    var hpRegenPerLevel: Double? 
 
    var mana: Int? 
 
    var manaPerLevel: Int? 
 
    var manaRegen: Double? 
 
    var manaRegenPerLevel: Double? 
 
    
 
    
 
    init(hp: Int, hpPerLevel: Int, hpRegen: Double, hpRegenPerLevel: Double, mana: Int, manaPerLevel: Int, manaRegen: Double, manaRegenPerLevel: Double) { 
 
     self.hp = hp 
 
     self.hpPerLevel = hpPerLevel 
 
     self.hpRegen = hpRegen 
 
     self.hpRegenPerLevel = hpRegenPerLevel 
 
     self.mana = mana 
 
     self.manaPerLevel = manaPerLevel 
 
     self.manaRegen = manaRegen 
 
     self.manaRegenPerLevel = manaRegenPerLevel 
 
    } 
 
    
 
    
 
} 
 

 
class Talent { 
 
    var id: String? 
 
    var name: String? 
 
    var description: String? 
 
    var cooldown: Double? 
 
    var prerequisite: String? 
 
    var icon: String? 
 
    
 

 
    
 
    init(id: String, name: String, description: String, cooldown: Double, prerequisite: String, icon: String) { 
 
     self.id = id 
 
     self.name = name 
 
     self.description = description 
 
     self.cooldown = cooldown 
 
     self.prerequisite = prerequisite 
 
     self.icon = icon 
 
    } 
 
    
 
    
 
} 
 

 
class Ability { 
 
    var id: String? 
 
    var name: String? 
 
    var description: String? 
 
    var shortcut: String? 
 
    var cooldown: Double? 
 
    var manaCost: Double? 
 
    var manaCostPerSecond: Double? 
 
    var aimType: String? 
 
    var heroic: Bool? 
 
    var trait: Bool? 
 
    var mount: Bool? 
 
    var icon: String? 
 
    
 
    init(id: String, name: String, description: String, shortcut: String, cooldown: Double, manaCost: Double, manaCostPerSecond: Double, aimType: String, heroic: Bool, trait: Bool, mount: Bool, icon: String){ 
 
     self.id = id 
 
     self.name = name 
 
     self.description = description 
 
     self.shortcut = shortcut 
 
     self.cooldown = cooldown 
 
     self.manaCost = manaCost 
 
     self.manaCostPerSecond = manaCostPerSecond 
 
     self.aimType = aimType 
 
     self.heroic = heroic 
 
     self.trait = trait 
 
     self.mount = mount 
 
     self.icon = icon 
 

 
    } 
 
    
 
} 
 

 
func parseData() { 
 
    let urlString = "http://heroesjson.com/heroes.json" 
 
    let session = NSURLSession.sharedSession() 
 
    let url = NSURL(string: urlString)! 
 
    
 
    session.dataTaskWithURL(url) { (data: NSData?, response:NSURLResponse?, error: NSError?) -> Void in 
 
     
 
     if let responseData = data { 
 
      
 
      do { 
 
       let json = try NSJSONSerialization.JSONObjectWithData(responseData, options: NSJSONReadingOptions.AllowFragments) 
 
       
 
       if let dict = json as? [Dictionary<String, AnyObject>] { 
 

 
        for x in 0 ..< dict.count { 
 
         
 
         
 
         if let id = dict[x]["id"], let attributeid = dict[x]["attributeid"], let name = dict[x]["name"], let title = dict[x]["title"], let description = dict[x]["description"], let role = dict[x]["role"], let type = dict[x]["type"], let gender = dict[x]["gender"], let franchise = dict[x]["franchise"], let difficulty = dict[x]["difficulty"], let icon = dict[x]["icon"] { 
 
          
 
          let hero = Hero(id: id as! String, attributeid: attributeid as! String, name: name as! String, title: title as! String, description: description as! String, role: role as! String, type: type as! String, gender: gender as! String, franchise: franchise as! String, difficulty: difficulty as! String, icon: icon as! String) 
 
          
 
          // Parse Ratings Class 
 
          
 
          if let dataArray = dict[x]["ratings"] as? Dictionary<String, Int> { 
 
           
 
           if let damage = dataArray["damage"], let utility = dataArray["utility"], let survivability = dataArray["damage"], let complexity = dataArray["complexity"] { 
 
            
 
            let rating = Ratings(damage: damage , utility: utility , survivability: survivability , complexity: complexity) 
 
            hero.ratings = rating 
 
            //print("\(hero.name) has a damage rating of \(hero.ratings!.damage)") 
 
            
 
           } 
 
          } 
 
          
 
          //Parse Stats Class 
 
          if let statsArray = dict[x]["stats"] as? Dictionary<String, AnyObject> { 
 
           
 

 
           if let dummy = statsArray[hero.id!]{//error handleing for vikings - parsing without this causes errors 
 
            
 
            
 
            if let hp = statsArray[hero.id!]!["hp"], let hpPerLevel = statsArray[hero.id!]!["hpPerLevel"], let hpRegen = statsArray[hero.id!]!["hpRegen"], let hpRegenPerLevel = statsArray[hero.id!]!["hpRegenPerLevel"], let mana = statsArray[hero.id!]!["mana"], let manaPerLevel = statsArray[hero.id!]!["manaPerLevel"], let manaRegen = statsArray[hero.id!]!["manaRegen"], let manaRegenPerLevel = statsArray[hero.id!]!["manaRegenPerLevel"] { 
 
             
 
             
 
             let stats = Stats(hp: hp as! Int, hpPerLevel: hpPerLevel as! Int, hpRegen: hpRegen as! Double, hpRegenPerLevel: hpRegenPerLevel as! Double, mana: mana as! Int, manaPerLevel: manaPerLevel as! Int, manaRegen: manaRegen as! Double, manaRegenPerLevel: manaRegenPerLevel as! Double) 
 
             
 
             
 
             hero.stats = stats 
 
            } 
 
            
 
           }//closes let dummy 
 
           
 
           
 
          } 
 
          
 
          //Parse Talent Class 
 
          
 
          if let talentsDict = dict[x]["talents"] as? Dictionary<String, AnyObject> { 
 
           for (index, talentsAtLevel) in talentsDict { 
 
            
 
            var talents = [Talent]() 
 
            
 
            for item in talentsAtLevel as! [AnyObject] { 
 
            
 
             let id = item["id"] 
 
             let name = item["name"] 
 
             let description = item["description"] 
 
             let cooldown = item["cooldown"]! ?? 0.00 
 
             let prerequisite = item["prerequisite"]! ?? "" 
 
             let icon = item["icon"] 
 
             
 
             
 
             let sId = id as? String 
 
             let sName = name as? String 
 
             let sDescription = description as? String 
 
             let iCooldown = cooldown as! Double 
 
             let sPrerequisite = prerequisite as! String 
 
             let sIcon = icon as? String 
 
             let talent = Talent(id: sId!, name: sName!, description: sDescription!, cooldown: iCooldown, prerequisite: sPrerequisite, icon: sIcon!) 
 
             talents.append(talent) 
 
             
 
            } 
 
            hero.talents = ["\(index)": talents] 
 
           } 
 
          } 
 
          
 
          //Parse Ability Class 
 
          
 
          if let abilitiesDict = dict[x]["abilities"] as? Dictionary<String, AnyObject> { 
 
           for (index, abilitiesAtLevel) in abilitiesDict { //index = heroid 
 
            
 
            var abilities = [Ability]() 
 
            
 
            for item in abilitiesAtLevel as! [AnyObject] { //item = ability 
 
             
 
             let id = item["id"]! ?? "" 
 
             let name = item["name"]! ?? "" 
 
             let description = item["description"]! ?? "" 
 
             let shortcut = item["shortcut"]! ?? "" 
 
             let cooldown = item["cooldown"]! ?? 0.0 
 
             let manaCost = item["manaCost"]! ?? 0.0 
 
             let manaCostPerSecond = item["manaCostPerSecond"]! ?? 0.0 
 
             let aimType = item["aimType"]! ?? "" 
 
             let heroic = item["heroic"]! ?? false 
 
             let trait = item["trait"]! ?? false 
 
             let mount = item["mount"]! ?? false 
 
             let icon = item["icon"]! ?? "" 
 
             
 
             
 
             let sId = id as? String 
 
             let sName = name as? String 
 
             let sDescription = description as? String 
 
             let sShortcut = shortcut as? String 
 
             let sCooldown = cooldown as? Double 
 
             let sManaCost = manaCost as? Double 
 
             let sManaCostPerSecond = manaCostPerSecond as? Double 
 
             let sAimType = aimType as? String 
 
             let sHeroic = heroic as? Bool 
 
             let sTrait = trait as? Bool 
 
             let sMount = mount as? Bool 
 
             let sIcon = icon as? String 
 
             let ability = Ability(id: sId!, name: sName!, description: sDescription!, shortcut: sShortcut!, cooldown: sCooldown!, manaCost: sManaCost!, manaCostPerSecond: sManaCostPerSecond!, aimType: sAimType!, heroic: sHeroic!, trait: sTrait!, mount: sMount!, icon: sIcon!) 
 
             abilities.append(ability) 
 
             
 
             
 
            } 
 
            hero.abilities = ["\(index)": abilities] 
 

 
           } 
 
          } 
 
          
 
          heroes.append(hero) 
 
          
 
         } 
 
        } 
 
        
 
       } 
 
      } catch { 
 
       print("Could not serialize") 
 
      } 
 
     } 
 
     
 
     }.resume() 
 
}