2017-08-05 90 views
0

我有以下swift3代碼。 JSON可以爲$ 0 [2]值返回一個NSNull值。SWIFT3 JSON NSNull問題

struct Player3 { 
    let name : String 
    var score : String 
    let avatar : String 
} 

class HistoricLeagueVC: UITableViewController { 

    var players = [Player3]() 

    override func viewDidLoad() { 
     super.viewDidLoad() 



     let urlString = "https://str8red.com/jsonoverallleaderboard/1025/" 

     let url = URL(string: urlString) 
     URLSession.shared.dataTask(with:url!) { (data, response, error) in 
      if error != nil { 
       print("there was an error") 
      } else { 
       do { 
        let parsedData = try JSONSerialization.jsonObject(with: data!) as! [[String]] 

        self.players = parsedData.map { Player3(name: $0[0], score: $0[1], avatar: $0[2]) } 

        print(self.players.count) 
        DispatchQueue.main.async { 
         self.tableView.reloadData() 
        } 

       } catch let error as NSError { 
        print(error) 
       } 
      } 

      }.resume() 

    } 

我試圖將它轉換爲空字符串而沒有成功。我也嘗試設置默認字符串,如"https://str8red.com/static/no_profile_picture.png",理想情況下我想這樣做。

在終端狀態Could not cast value of type 'NSNull' (0xed1c78) to 'NSString' (0x57b6b8).

任何幫助的錯誤,將不勝感激。

+1

你爲什麼要投「as! [[String]]'如果你知道可能沒有字符串,但是那裏有NSNulls?我認爲這是代碼崩潰的行 – luk2302

+0

這正是代碼崩潰的地方。最初所有配置文件都有一張圖片,因此它們都不是NSNull,但顯然有些人沒有添加個人資料圖片。所以現在我不知道如何處理NSNull。思考? –

+0

這是做錯的方法,首先如果可能的話應該避免!只要你可以,最好使用警戒語句。然後,你應該有一些json樹,從這個不可能告訴什麼是[0],[1],[2],如果它存在 –

回答

0

不要投給[[String]],則:

let parsedData = try JSONSerialization.jsonObject(with: data!) as! [[Any]] 

self.players = parsedData.map { Player3(
    name: ($0[0] as? String) ?? "", 
    score: ($0[1] as? String) ?? "", 
    avatar: $0[2] as? String, // keeping `nil` here 
)} 

你應該甚至可能as! [[Any]]以更安全的方式做(使用as?),但上面會工作。

+0

當我在你的代碼中複製時,它在最後一行強制執行了一些更正:「avatar:($ 0 [2] as?String)!//保留'nil'這裏 } 然後,錯誤在同一個地方有同樣的錯誤:/ –

+0

@AlanTingey如果你把'!'你正在恢復到以前的行爲。我認爲,因爲不是所有的人都有化身,那麼'化身「應該是可選的。如果它不是可選的,則使用'($ 0 [2]作爲?字符串)?? 「」)而不是'!'。 – Sulthan

+0

我剛把「,」改成了?? 「」,它的工作原理。希望這是有道理的? –

0

如果輸入數據出現任何問題,您的代碼將會慘遭崩潰。問問你的老闆他/她是否可以。我不會。這裏是你將如何崩潰:如果數據==零(但它不應該是如果錯誤==零)。您發現無法解析數據而不會崩潰的問題。如果數據不解析爲數組,則會崩潰,如果數組的元素不是全部數組,則會崩潰,如果內部數組內的元素不全是字符串,則會崩潰,並且如果任何內部數組包含兩個元素或更少的字符串。我會說這是非常不可接受的。

我的策略是:如果響應無法解析或不是數組數組,則忽略它,使self.players保持不變。如果有數組數組,重置self.players,然後爲每個包含至少三個項目的數組添加一個播放器,其中前兩個項必須是字符串。

guard data != nil else { return } 
guard let parsed = try? NSJSONSerialization(with: data!) else { return } 
guard let arrays = parsed as? [[Any]] else { return } 

self.players.removeAll() 
for array in arrays { 
    guard array.count >= 3, 
    let name = array [0] as? String, 
    let score = array [1] as? String else { continue } 
    let avatar = array [2] as? String ?? "" 
    self.players.append(Player3 (name: name, score: score, avatar: avatar)) 
} 

將這樣的東西移動到一個單獨的方法是一個好主意。添加任何錯誤處理或記錄你覺得是適當的。

+0

非常感謝。幸運的是,沒有老闆,我們只是爲了籌集一點錢用於慈善事業而「投」一些東西。當我複製你的代碼時,我得到了「使用未解析的標識符'解析'」和數組相同。也許我把它複製到了錯誤的部分? –

+0

這是我剛輸入的代碼。如果有任何錯誤,編譯器會告訴你並且你修復它們。 – gnasher729

+0

瞭解了吧:) –