【问题标题】:The app crashes when adding new keys in firestore在 Firestore 中添加新密钥时应用程序崩溃
【发布时间】:2017-12-18 06:57:15
【问题描述】:

我按照 Google 的 github 示例做了一个测试应用程序,但做了一些更改(firestore 中使用的键和过滤器更少)。

问题是这样的,当我在 firestore 中添加新键时应用程序崩溃,但该应用程序可以使用之前添加的两个键。

fatalError("error") 上崩溃并显示错误。我不明白为什么应用程序使用两个键可以工作,但如果我开始使用第三个键 (hall),那么应用程序就会崩溃。

可能是什么问题?

这是我的代码:

class ViewControllerTwo: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet var tableView: UITableView!

    private var sweets: [Sweet] = []
    private var document: [DocumentSnapshot] = []

    fileprivate var query: Query? {
        didSet {
            if let listener = listener {
                listener.remove()
            }
        }
    }

    private var listener: FIRListenerRegistration?

    fileprivate func observeQuery() {

        guard let query = query else { return }

        stopObserving()

        listener = query.addSnapshotListener { [unowned self] (snapshot, error) in

            guard let snapshot = snapshot else {

                print("Error fetching snapshot results: \(error!)")

                return

            }

            let models = snapshot.documents.map { (document) -> Sweet in

                if let model = Sweet(dictionary: document.data()) {

                    return model

                } else {

                    fatalError("error")

                }

            }

            self.sweets = models

            self.document = snapshot.documents

            self.tableView.reloadData()

        }

    }

    @IBAction func filterButton(_ sender: Any) {
        present(filters.navigationController, animated: true, completion: nil)    
    }

    lazy private var filters: (navigationController: UINavigationController, filtersController: FilterViewController) = {
        return FilterViewController.fromStoryboard(delegate: self)
    }()

    fileprivate func stopObserving() {
        listener?.remove()
    }

    fileprivate func baseQuery() -> Query {
        return Firestore.firestore().collection("sweets").limit(to: 50)    
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        query = baseQuery()    
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)

        observeQuery()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(true)

        stopObserving()    
    }

    deinit {
        listener?.remove()    
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return sweets.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ViewControllerCell

        let sweet = sweets[indexPath.row]

        cell.studioNameLabel.text = sweet.name
        cell.studioAddressLabel.text = sweet.content
        cell.hallNameLabel.text = sweet.hall

        return cell

    }

}

extension ViewControllerTwo: FiltersViewControllerDelegate {

    func query(withCategory title: String?) -> Query {

        var filtered = baseQuery()

        if let title = title, !title.isEmpty {
            filtered = filtered.whereField("title", isEqualTo: title)
        }

        return filtered
    }

    func controller(_ controller: FilterViewController, didSelectCategory title: String?) {

        let filtered = query(withCategory: title)

        self.query = filtered
        observeQuery()

    }
}

class ViewControllerCell: UITableViewCell {

    @IBOutlet weak var studioNameLabel: UILabel!
    @IBOutlet weak var studioAddressLabel: UILabel!
    @IBOutlet weak var hallNameLabel: UILabel!

}

还有我的结构:

protocol DocumentSerializable  {
    init?(dictionary:[String:Any])
}
struct Sweet {
    var name:String
    var content:String
    var hall:String
    var dictionary:[String:Any] {
        return [
            "name": name,
            "content" : content,
            "hall" : hall
        ]
    }
}
extension Sweet : DocumentSerializable {

    static let title = [
        "one",
        "two",
        "three",
        "four"
    ]
    init?(dictionary: [String : Any]) {
        guard let name = dictionary["name"] as? String,
            let content = dictionary["content"] as? String,
            let hall = dictionary["hall"] as? String else { return nil }

        self.init(name: name, content: content, hall: hall)
    }
}

我在 Google Drive 中的项目

google drive

google service info.plist

【问题讨论】:

  • 尝试打印Sweet(dictionary: document.data())并检查它是否为nil
  • @DharmeshKheni in fatalError()?
  • 以上if let model = Sweet(dictionary: document.data())
  • @DharmeshKheni 我得到了一个 nil :( 我该如何解决这个问题?在控制台中我看到 dropbox.com/s/64xrj556i368sp4/…
  • @DharmeshKheni 但如果我使用两个键,我不会得到 nil

标签: ios swift xcode google-cloud-firestore


【解决方案1】:

向现有结构添加任何新密钥后,您只需重新安装应用程序。

所以你应该在结构实现之前决定你需要什么键。或者,如果您以后添加新密钥,您可以重新安装应用程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 2021-10-17
    • 2012-11-19
    • 1970-01-01
    • 2019-02-01
    • 2022-11-02
    相关资源
    最近更新 更多