每次打开我的应用程序进行连接时,都会导致错误。我认为我正确地将价值观转换为[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 服务返回一个值 <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
}
FIRDataSnapshot
应该在请求成功时返回Any?
,失败时 - 它将返回null
。因为我们不知道请求何时会成功或失败,所以我们需要安全地解开这个可选包。在您的错误中,您强行向下转换 ( as!
),如果快照数据未按[String: String]
返回,即如果您的请求返回 null
,这将崩溃。 有条件下放 ( 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