2017-12-18 334 views
1

我使用github做了一个测试应用程序,后面跟着Google的例子,但有一些变化(在firestore中使用的键较少,过滤器少一些)。在firestore中添加新密钥时,应用程序崩溃

问题是这样的,当我在firestore中添加新密钥时,应用程序崩溃,但该应用程序使用了先前添加的两个密钥。

崩溃并显示错误fatalError("error")。我不明白为什么有两个键的应用程序工作,但如果我开始使用第三个键(大厅),那么应用程序崩溃。

可能是什么问题?

这是我的代码:

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 service info.plist

+0

尝试打印'Sweet(dictionary:document.data())'并检查它是否为'nil' –

+0

@DharmeshKheni in'fatalError()'? – Dima

+0

以上'如果让模型=甜(字典:document.data())' –

回答

0

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

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