Ios Xcode:为什么在展开时我的可选值为nill?
有人可以看看我的代码,告诉我为什么我的值是零。如果你需要我发布其他文件,我会的。该项目主要是firebase,每当您试图在应用程序中发布时,应用程序就会崩溃。我相信当屏幕必须更新时,它会崩溃,因为数据正在访问数据库Ios Xcode:为什么在展开时我的可选值为nill?,ios,swift,firebase,google-cloud-firestore,Ios,Swift,Firebase,Google Cloud Firestore,有人可以看看我的代码,告诉我为什么我的值是零。如果你需要我发布其他文件,我会的。该项目主要是firebase,每当您试图在应用程序中发布时,应用程序就会崩溃。我相信当屏幕必须更新时,它会崩溃,因为数据正在访问数据库 import UIKit import FirebaseFirestore class FeedVC: UITableViewController { var db = Firestore.firestore() var postArray = [Posts]
import UIKit
import FirebaseFirestore
class FeedVC: UITableViewController {
var db = Firestore.firestore()
var postArray = [Posts]()
override func viewDidLoad() {
super.viewDidLoad()
//db = Firestore.firestore()
//loadData()
// checkForUpdates()
}
override func viewDidAppear(_ animated: Bool){
loadData()
checkForUpdates()
}
func loadData() {
db.collection("posts").getDocuments() {
querySnapshot, error in
if let error = error {
print("\(error.localizedDescription)")
}else{
self.postArray = querySnapshot!.documents.flatMap({Posts(dictionary: $0.data())})
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
func checkForUpdates() {
db.collection("posts").whereField("timeStamp", isGreaterThan: Date())
.addSnapshotListener {
querySnapshot, error in
guard let snapshot = querySnapshot else {return}
snapshot.documentChanges.forEach {
diff in
if diff.type == .added {
self.postArray.append(Posts(dictionary: diff.document.data())!)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
}
@IBAction func composePost(_ sender: Any) {
let composeAlert = UIAlertController(title: "New Post", message: "Enter your name and message", preferredStyle: .alert)
composeAlert.addTextField { (textField:UITextField) in
textField.placeholder = "Your name"
}
composeAlert.addTextField { (textField:UITextField) in
textField.placeholder = "Your message"
}
composeAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
composeAlert.addAction(UIAlertAction(title: "Send", style: .default, handler: { (action:UIAlertAction) in
if let name = composeAlert.textFields?.first?.text, let content = composeAlert.textFields?.last?.text {
let newSweet = Posts(name: name, content: content, timeStamp: Date())
var ref:DocumentReference? = nil
ref = self.db.collection("posts").addDocument(data: newSweet.dictionary) {
error in
if let error = error {
print("Error adding document: \(error.localizedDescription)")
}else{
print("Document added with ID: \(ref!.documentID)")
}
}
}
}))
self.present(composeAlert, animated: true, completion: nil)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let sweet = postArray[indexPath.row]
cell.textLabel?.text = "\(sweet.name): \(sweet.content)"
cell.detailTextLabel?.text = "\(sweet.timeStamp)"
return cell
}
}
import Foundation
import FirebaseFirestore
protocol DocumentSerializable {
init?(dictionary:[String:Any])
}
struct Posts {
var name:String
var content:String
var timeStamp:Date
var dictionary:[String:Any] {
return [
"name":name,
"content" : content,
"timeStamp" : timeStamp
]
}
}
extension Posts : DocumentSerializable {
init?(dictionary: [String : Any]) {
guard let name = dictionary["name"] as? String,
let content = dictionary["content"] as? String,
let timeStamp = dictionary ["timeStamp"] as? Date else {return nil}
self.init(name: name, content: content, timeStamp: timeStamp)
}
}
使用
时间戳
代替日期
import FirebaseFirestore
guard let stamp = data["timeStamp"] as? Timestamp else { return nil }
根据评论,这条线正在崩溃
self.postArray.append(Posts(dictionary: diff.document.data())!)
它崩溃了,因为你正在强制展开一个为零的变量
Posts(dictionary: diff.document.data())! <- ! means 'I guarantee you will never be nil'
这里有令人不快的代码
guard
let name = dictionary["name"] as? String,
let content = dictionary["content"] as? String,
let timeStamp = dictionary ["timeStamp"] as? Date
else {return nil} //OFFENDING CODE!
如果字典中不存在这些变量中的任何一个,它将失败,并返回nil
所以。。。您的一个文档不包含这些字段之一
您还可以参考Firestore指南了解如何编写日期。查看中的示例代码
此外,Firestore没有内部日期类型,因此请改用Timestamp.dateValue。在此处查看它它崩溃可能是因为您正在更新viewDidLoad下的表视图数据。我也应该将其移动到何处?崩溃发生在-self.postArray.append(Posts(dictionary:diff.document.data())!)上,请使用ViewWillDisplay或ViewDidDisplay进行尝试。我在ViewWillDisplay和ViewDidDisplay中进行了尝试,但仍然出现错误。
guard
let name = dictionary["name"] as? String,
let content = dictionary["content"] as? String,
let timeStamp = dictionary ["timeStamp"] as? Date
else {return nil} //OFFENDING CODE!