Ios 斯威夫特的火力基地。无法强制转换类型为';NSNull';至';NSDictionary';

Ios 斯威夫特的火力基地。无法强制转换类型为';NSNull';至';NSDictionary';,ios,swift,firebase,firebase-realtime-database,Ios,Swift,Firebase,Firebase Realtime Database,每次在连接时打开我的应用程序,都会导致错误。我认为我将值正确地转换为[String:String],但不是。解决这个问题的正确方法是什么 class func info(forUserID: String, completion: @escaping (User) -> Swift.Void) { FIRDatabase.database().reference().child("users").child(forUserID).child("credentials").obse

每次在连接时打开我的应用程序,都会导致错误。我认为我将值正确地转换为
[String:String]
,但不是。解决这个问题的正确方法是什么

 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)


当Web服务返回值
时,它被表示为
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
}

FIRDataSnapshot
在成功请求时应返回
Any?
,在失败时-它将返回
null
。因为我们不知道请求何时会成功或失败,所以我们需要安全地打开此可选文件。在错误中,您强制向下转换(
as!
),如果快照数据未作为
[String:String]
返回,即如果您的请求返回
null
,则会崩溃。如果快照数据的类型不是
[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

json结构是什么样子的?在强制展开之前记录快照的值。另外,一般避免使用强制展开-如果let或
guard
语句出现错误,请使用
语句。错误消息显示
快照。值
(与
nil
不同),并且转换到字典失败。感谢您的帮助。我得到了它。解决方案是使用if-let语句。还有,在什么情况下使用它是好的呢?@vadian对于nil有什么不同?