2016-08-22 143 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() 
 
}