2017-01-19 106 views
1

每當我的應用程序打開連接時,都會導致錯誤。我認爲我正確投射值爲[String: String],但不是。解決這個問題的正確方法是什麼?Swift中的Firebase。無法將類型'NSNull'的值轉換爲'NSDictionary'

class func info(forUserID: String, completion: @escaping (User) -> Swift.Void) { 
    FIRDatabase.database().reference().child("users").child(forUserID).child("credentials").observeSingleEvent(of: .value, with: { (snapshot) in 

     //This line is the reason of the problem. 
     let data = snapshot.value as! [String: String] 
     let name = data["name"]! 
     let email = data["email"]! 
     let link = URL.init(string: data["profile"]!) 
     URLSession.shared.dataTask(with: link!, completionHandler: { (data, response, error) in 
      if error == nil { 
       let profilePic = UIImage.init(data: data!) 
       let user = User.init(name: name, email: email, id: forUserID, profilePic: profilePic!) 
       completion(user) 
      } 
     }).resume() 
    }) 
} 

錯誤說

無法投類型的值 'NSNull'(0x1ae148588)爲 'NSDictionary的' (0x1ae148128)。

+0

那麼你的JSON結構是什麼樣子? – mjr

+1

在強制解包之前記錄快照的值。另外,避免在一般情況下使用強制解包 - 使用'if let'或'guard'語句代替 –

+0

錯誤消息表明'snapshot.value'爲''(與'nil'不同),並且轉換爲字典失敗。 – vadian

回答

1

當web服務返回值<null>時,它將被表示爲NSNull對象。這是一個實際的對象,並將其與nil進行比較將返回false

這是我做的:

if let json = snapshot.value as? [String: String] { 
    //if it's possible to cast snapshot.value to type [String: String] 
    //this will execute 
} 
1

FIRDataSnapshot應當在請求成功返回Any?,失敗 - 它會返回null。因爲我們不知道請求何時會成功或失敗,所以我們需要安全地解開這個可選項。如果快照數據未以[String: String]的形式返回,即您的請求返回null,那麼在錯誤中,您將強制下轉(as!),這將會崩潰。有條件的向下轉換(as?)安全返回nil,如果你的快照數據的類型不是[String: String]

TL的; DR - 你需要有條件垂頭喪氣

// So rather than 
let data = snapshot.value as! [String: String] 

// Conditionally downcast 
if let data = snapshot.value as? [String: String] { 
    // Do stuff with data 
} 

// Or.. 
guard let data = snapshot.value as? [String: String] else { return } 
// Do stuff with data 
相關問題