如何在不允许可选值的情况下使用Firebase
我是iOS开发的新手,我明白在初始化对象时允许可选值不是一种“好公民”技术。 话虽如此,我已经读过,总是设置值是一个好习惯,如下所示:
class Item{ var name: String var color: String init(name: String, color: String) { self.name = name self.color = color } }
这看起来很整洁,但我怎样才能做与Firebase一起工作的事情呢? 看看到目前为止我得到了什么:
private func loadPosts(){ databaseHandle = ref.child("users/\(self.user.uid)/posts").observe(.value, with:{(snapshot) in var newPosts = [Post]() for itemSnapShot in snapshot.children { let post = Post(snapshot: itemSnapShot as! FIRDataSnapshot) newPosts.append(post!) } self.posts = newPosts self.tableView.reloadData() }) }
这个家伙放在我的PostsViewController里,我有桌子视图。 这是我的模特:
class Post { var ref: FIRDatabaseReference? var title: String? var answer: String? var contentUrl: String? var photoUrl: String? var createdAt: String? var feeling: String? var kind: String? var text: String? var uid: String? var measurements: Dictionary? //MARK: Initialization init?(snapshot: FIRDataSnapshot){ ref = snapshot.ref let data = snapshot.value as! Dictionary title = data["title"]! as? String answer = data["answer"] as? String contentUrl = data["content_url"] as? String photoUrl = data["photo_url"] as? String createdAt = data["created_at"] as? String feeling = data["feeling"] as? String kind = data["kind"] as? String text = data["text"] as? String uid = data["uid"] as? String measurements = data["measurements"] as? Dictionary } }
我不确切知道为什么,但那些问号感觉不太正确,现在我得到一些零指针错误,我认为我应该能够通过使用“好公民”技术来避免。
那么,是否有人知道如何使用Firebase遵循Swift最佳实践?
要么您希望允许Post类的属性为nil,要么不允许。
如果你这样做,那没关系。 您发布的代码允许其中任何一个为零。 您只需在每次需要时安全地访问每个属性。
如果不这样做,那么不要将它们作为可选项。 然后在init
,如果快照中没有值,则需要确保没有任何属性设置为nil
。
class Post { var ref: FIRDatabaseReference var title: String var answer: String var contentUrl: String var photoUrl: String var createdAt: String var feeling: String var kind: String var text: String var uid: String var measurements: [String : String] //MARK: Initialization init?(snapshot: FIRDataSnapshot) { if let data = snapshot.value as? [String : Any] { self.ref = snapshot.ref title = data["title"] as? String ?? "" answer = data["answer"] as? String ?? "" contentUrl = data["content_url"] as? String ?? "" photoUrl = data["photo_url"] as? String ?? "" createdAt = data["created_at"] as? String ?? "" feeling = data["feeling"] as? String ?? "" kind = data["kind"] as? String ?? "" text = data["text"] as? String ?? "" uid = data["uid"] as? String ?? "" measurements = data["measurements"] as? [String : String] ?? [:] } else { return nil } } }
请注意这是如何确保有适当的快照。 请注意,如果快照中没有值,如何为每个属性设置默认值。 显然你可以分配你想要的任何默认值。 我以空字符串为例。
即使您希望允许属性为nil
,您至少应该更新代码以检查上面代码中的有效快照。
当然,你可以有一些组合,其中一些属性不能nil
,有些属性可以。 这取决于您的需求。
首先,您可以在数据模型中使用选项,只要您将来稍后为其指定值即可。
我建议使用ObserveSingleEvent()
,你应该使用完成处理程序来ObserveSingleEvent()
它。 如果您不知道完成处理程序: 链接
我建议:
•不要将数据库引用放在类模型中,而不是使用Dictionary
只使用[String: AnyObject]?
•使您的post数组公开,以便可以访问tableview。
这是一个例子:
class func getPosts(uid: String, _ completion: @escaping (_ posts: [Post]?, _ error: Error?) -> Void) { //update inside users node var posts = [Post]() Firebase.databaseRef.child("users").child(uid).child("posts").observeSingleEvent(of: FIRDataEventType.value, with: { (dataSnapshot) in guard let postsDictionary = dataSnapshot.value as? [String: AnyObject] else { completion(nil, nil) return } let n = postsDictionary.count for postDictionary in postsDictionary { let post = Post() post.userID = uid if let content = postDictionary.value["content"] as? String { post.content = content } if let imageURL = postDictionary.value["imageURL"] as? String { post.imageURL = imageURL } if let timeStamp = postDictionary.key as String! { if let date = timeStamp.convertToDate() { post.timeStamp = date } post.postIdentifier = timeStamp } posts.append(post) if posts.count == n { // Sort the array by the newest post let sortedPosts = posts.sorted(by: { $0.timeStamp.compare($1.timeStamp) == .orderedDescending }) completion(sortedPosts, nil) } } }) { (error) in completion(nil, error) } }
分配到tableview如:
getPosts(uid: Current.user.userID!) { (posts, error) in guard error == nil else { print(error.debugDescription) return } cell.label.text = posts[indexPath.item].content
- 在Swift中解码JSON Web Tokens
- 使用customView的UIBarButtonItem类似于Flexible-Space项目
- 如何通过NSData播放audio?
- 尝试启用推送通知时,找不到应用程序的有效“aps-environment”权利字符串
- UITableView方法“indexPathForRowAtPoint:”的奇怪行为
- SKNode无法找到childNodeWithName:
- corebluetooth和ios状态
- 更新到SDK 1.3.1后,GMSMapView上的拖动/平移手势未被捕获
- 如何将一个NSArray的string变成一个唯一的string数组,按照相同的顺序?