在 Swift 中显示所有使用 Firebase 的帖子?
Displaying all posts using Firebase in Swift?
我的目标是当用户打开该应用程序时,他们将看到该应用程序的每个用户的每个 post。我的数据树如下:
- posts
- UID
- postKey
--attributes
- users
- UID
- attributes
这是一个例子:
-posts
-74anqEXU8kQHVr7IKoO3N9NNqDh1
-MLzvs5VvXB_z7fhbh2p
created_at: 1605242945.969368
image_height: 414.6865671641791
image_url: "https://firebasestorage...."
-MLzvun01fNXNRbn7TPv
-MM7zGyZ7GbenhlisJUZ
-VGxqdzc2CkWWn39pa8xUofEWgNm2
-pNvGg84JR0TbXvS4XlX8KbfBasz2
-users
-74anqEXU8kQHVr7IKoO3N9NNqDh1
-VGxqdzc2CkWWn39pa8xUofEWgNm2
我知道我必须对所有post做一个快照,然后显示在主控制器(SearchViewController)的viewDidLoad()中。我不知道如何显示所有 posts。
此代码用于显示当前用户的 posts,存储在名为 UserService.swift:
的文件中
static func posts(for user: User, completion: @escaping ([Post]) -> Void) {
let ref = Database.database().reference().child("posts").child(user.uid)
ref.observeSingleEvent(of: .value, with: { (snapshot) in
guard let snapshot = snapshot.children.allObjects as? [DataSnapshot] else {
return completion([])
}
let dispatchGroup = DispatchGroup()
let posts: [Post] = snapshot.reversed().compactMap {
guard let post = Post(snapshot: [=13=]) else { return nil }
dispatchGroup.enter()
SaveService.isPostSaved(post) { (isSaved) in
post.isSaved = isSaved
dispatchGroup.leave()
}
return post
}
dispatchGroup.notify(queue: .main, execute: {
completion(posts)
})
})
}
然后在 SearchViewController 的 ViewDidLoad() 中:
UserService.posts(for: User.current) { (posts) in
self.posts = posts
self.tableView.reloadData()
}
但是我如何为所有 post 执行此操作。当我尝试以下操作时,它不会让我指定一个随机用户:
let ref = Database.database().reference().child("posts").child(User)
知道我可以在“.child(User”框中放入什么来完成这项工作吗?或者如何创建 for 循环以正确迭代?
*编辑
这是有效的方法:
static func allPosts(completion: @escaping ([Post]) -> Void) {
let ref = Database.database().reference().child("posts")
ref.observeSingleEvent(of: .value, with: { (snapshot) in
var postsArray = [Post]()
for userSnapshot in snapshot.children {
guard let snapshot = (userSnapshot as AnyObject).children.allObjects as? [DataSnapshot] else {
return completion([])
}
let dispatchGroup = DispatchGroup()
let posts: [Post] = snapshot.reversed().compactMap {
guard let post = Post(snapshot: [=16=]) else { return nil }
postsArray
postsArray.append(post)
dispatchGroup.enter()
SaveService.isPostSaved(post) { (isSaved) in
post.isSaved = isSaved
dispatchGroup.leave()
}
return post
}
dispatchGroup.notify(queue: .main, execute: {
completion(postsArray)
})
}
})
}
你可以在JSON中观察更高一级,然后在回调中添加一个额外的循环:
let ref = Database.database().reference().child("posts")
ref.observeSingleEvent(of: .value, with: { (snapshot) in
for userSnapshot in snapshot.children {
guard let snapshot = userSnapshot.children.allObjects as? [DataSnapshot] else {
return completion([])
}
let dispatchGroup = DispatchGroup()
let posts: [Post] = snapshot.reversed().compactMap {
guard let post = Post(snapshot: [=10=]) else { return nil }
dispatchGroup.enter()
SaveService.isPostSaved(post) { (isSaved) in
post.isSaved = isSaved
dispatchGroup.leave()
}
return post
}
}
dispatchGroup.notify(queue: .main, execute: {
completion(posts)
})
})
我可能忽略了一些东西,但目标似乎是
when users open the app they will see every post from every user
如果是这样,有时越简单越好;加载所有帖子,遍历它们,为每个帖子创建 Post 对象,然后重新加载 tableview (?)
let postsRef = self.ref.child("posts") //self.ref points to my firebase
postsRef.observeSingleEvent(of: .value, with: { snapshot in
let allPosts = snapshot.children.allObjects as! [DataSnapshot]
for postSnap in allPosts {
let aPost = Post(initWithSnapshot: postSnap)
self.postsArrray.append(post) //
}
self.postTableView.reloadData()
}
这假设您的 Post class 有一个方便的 init 来从快照填充它的属性。如果是这样,请在其中将 isSaved 设置为 true,因为正在使用保存的数据调用便利 init。
如果您在应用程序启动或视图加载时调用它,则不需要回调和 dispatchQueues。
我的目标是当用户打开该应用程序时,他们将看到该应用程序的每个用户的每个 post。我的数据树如下:
- posts
- UID
- postKey
--attributes
- users
- UID
- attributes
这是一个例子:
-posts
-74anqEXU8kQHVr7IKoO3N9NNqDh1
-MLzvs5VvXB_z7fhbh2p
created_at: 1605242945.969368
image_height: 414.6865671641791
image_url: "https://firebasestorage...."
-MLzvun01fNXNRbn7TPv
-MM7zGyZ7GbenhlisJUZ
-VGxqdzc2CkWWn39pa8xUofEWgNm2
-pNvGg84JR0TbXvS4XlX8KbfBasz2
-users
-74anqEXU8kQHVr7IKoO3N9NNqDh1
-VGxqdzc2CkWWn39pa8xUofEWgNm2
我知道我必须对所有post做一个快照,然后显示在主控制器(SearchViewController)的viewDidLoad()中。我不知道如何显示所有 posts。
此代码用于显示当前用户的 posts,存储在名为 UserService.swift:
的文件中static func posts(for user: User, completion: @escaping ([Post]) -> Void) {
let ref = Database.database().reference().child("posts").child(user.uid)
ref.observeSingleEvent(of: .value, with: { (snapshot) in
guard let snapshot = snapshot.children.allObjects as? [DataSnapshot] else {
return completion([])
}
let dispatchGroup = DispatchGroup()
let posts: [Post] = snapshot.reversed().compactMap {
guard let post = Post(snapshot: [=13=]) else { return nil }
dispatchGroup.enter()
SaveService.isPostSaved(post) { (isSaved) in
post.isSaved = isSaved
dispatchGroup.leave()
}
return post
}
dispatchGroup.notify(queue: .main, execute: {
completion(posts)
})
})
}
然后在 SearchViewController 的 ViewDidLoad() 中:
UserService.posts(for: User.current) { (posts) in
self.posts = posts
self.tableView.reloadData()
}
但是我如何为所有 post 执行此操作。当我尝试以下操作时,它不会让我指定一个随机用户:
let ref = Database.database().reference().child("posts").child(User)
知道我可以在“.child(User”框中放入什么来完成这项工作吗?或者如何创建 for 循环以正确迭代?
*编辑
这是有效的方法:
static func allPosts(completion: @escaping ([Post]) -> Void) {
let ref = Database.database().reference().child("posts")
ref.observeSingleEvent(of: .value, with: { (snapshot) in
var postsArray = [Post]()
for userSnapshot in snapshot.children {
guard let snapshot = (userSnapshot as AnyObject).children.allObjects as? [DataSnapshot] else {
return completion([])
}
let dispatchGroup = DispatchGroup()
let posts: [Post] = snapshot.reversed().compactMap {
guard let post = Post(snapshot: [=16=]) else { return nil }
postsArray
postsArray.append(post)
dispatchGroup.enter()
SaveService.isPostSaved(post) { (isSaved) in
post.isSaved = isSaved
dispatchGroup.leave()
}
return post
}
dispatchGroup.notify(queue: .main, execute: {
completion(postsArray)
})
}
})
}
你可以在JSON中观察更高一级,然后在回调中添加一个额外的循环:
let ref = Database.database().reference().child("posts")
ref.observeSingleEvent(of: .value, with: { (snapshot) in
for userSnapshot in snapshot.children {
guard let snapshot = userSnapshot.children.allObjects as? [DataSnapshot] else {
return completion([])
}
let dispatchGroup = DispatchGroup()
let posts: [Post] = snapshot.reversed().compactMap {
guard let post = Post(snapshot: [=10=]) else { return nil }
dispatchGroup.enter()
SaveService.isPostSaved(post) { (isSaved) in
post.isSaved = isSaved
dispatchGroup.leave()
}
return post
}
}
dispatchGroup.notify(queue: .main, execute: {
completion(posts)
})
})
我可能忽略了一些东西,但目标似乎是
when users open the app they will see every post from every user
如果是这样,有时越简单越好;加载所有帖子,遍历它们,为每个帖子创建 Post 对象,然后重新加载 tableview (?)
let postsRef = self.ref.child("posts") //self.ref points to my firebase
postsRef.observeSingleEvent(of: .value, with: { snapshot in
let allPosts = snapshot.children.allObjects as! [DataSnapshot]
for postSnap in allPosts {
let aPost = Post(initWithSnapshot: postSnap)
self.postsArrray.append(post) //
}
self.postTableView.reloadData()
}
这假设您的 Post class 有一个方便的 init 来从快照填充它的属性。如果是这样,请在其中将 isSaved 设置为 true,因为正在使用保存的数据调用便利 init。
如果您在应用程序启动或视图加载时调用它,则不需要回调和 dispatchQueues。