如何为 Codable Swift 结构的字典制作 ForEach 循环(基于 Firestore 映射)
How to make ForEach loop for a Codable Swift Struct's Dictionary (based on Firestore map)
我正在尝试执行一个 ForEach 循环,列出用户可能拥有的所有社交媒体。这将在一个可滚动的列表上,相当于音乐流媒体应用程序有一个列表,列出了您保存在库中的所有歌曲。用户的社交媒体列表实际上是一个字典。
我的 MainViewModel class 实现了所有 Firebase 功能。见下文。
class MainViewModel: ObservableObject {
@Published var errorMessage = ""
@Published var user: User?
init() {
DispatchQueue.main.async {
self.isUserCurrentlyLoggedOut = FirebaseManager.shared.auth.currentUser?.uid == nil
}
readCodableUserWithMap()
}
@Published var isUserCurrentlyLoggedOut = false
func handleSignOut() {
isUserCurrentlyLoggedOut.toggle()
try? FirebaseManager.shared.auth.signOut()
}
func readCodableUserWithMap() {
guard let uid = FirebaseManager.shared.auth.currentUser?.uid else {
self.errorMessage = "Could not find firebase uid"
print("FAILED TO FIND UID")
return
}
let userID = uid
let docRef = FirebaseManager.shared.firestore.collection("users").document(userID)
docRef.getDocument { (document, error) in
if let err = error {
print(err.localizedDescription)
return
}
if let doc = document {
let user = try! doc.data(as: User.self)
if let mappedField = user.socials {
mappedField.forEach { print([=11=].key, [=11=].value) }
}
}
}
}
}
readCodableUserWithMap() 应该初始化代表用户的可编码结构。见下文。
struct User: Identifiable, Codable {
@DocumentID var id: String?
var socials: [String: String]?
var uid, email, name, bio, profileImageUrl: String?
var numSocials, followers, following: Int?
}
手头的问题: 在我的仪表板视图中,我试图列出用户可以拥有的所有社交媒体。我无法为我的用户创建一个 ForEach 循环。
我愿意:
ForEach(vm.user?.socials.sorted(by: >), id: \.key) { key, value in
linkDisplay(social: key, handler: value)
.listRowSeparator(.hidden)
}.onDelete(perform: delete)
这给了我以下错误:
可选类型“[Dictionary.Element] 的值?” (又名 'Optional<Array<(key: String, value: String)>>')必须解包为“[Dictionary.Element]”类型的值(又名 'Array<(key: String, value: String)>')
可选类型“[String : String]?”的值?必须解包以引用包装基类型“[String : String]”
的成员 'sorted'
我试过使用 ??但这不起作用,尽管我认为我做错了什么。强制展开是我尝试过的方法,但是当它是一个空字典时它使应用程序崩溃。
以防万一,这是数据库层次结构:firebase hierarchy
TLDR:我如何制作一个 ForEach 循环来列出我所有用户的媒体?
您有 vm.user
和 socials
作为选项。
ForEach
循环需要 non-optionals,所以
您可以尝试使用以下方法为 ForEach
循环解包。
if let user = vm.user, let socials = user.socials {
ForEach(socials.sorted(by: > ), id: \.key) { key, value in
linkDisplay(social: key, handler: value)
.listRowSeparator(.hidden)
}.onDelete(perform: delete)
}
我正在尝试执行一个 ForEach 循环,列出用户可能拥有的所有社交媒体。这将在一个可滚动的列表上,相当于音乐流媒体应用程序有一个列表,列出了您保存在库中的所有歌曲。用户的社交媒体列表实际上是一个字典。
我的 MainViewModel class 实现了所有 Firebase 功能。见下文。
class MainViewModel: ObservableObject {
@Published var errorMessage = ""
@Published var user: User?
init() {
DispatchQueue.main.async {
self.isUserCurrentlyLoggedOut = FirebaseManager.shared.auth.currentUser?.uid == nil
}
readCodableUserWithMap()
}
@Published var isUserCurrentlyLoggedOut = false
func handleSignOut() {
isUserCurrentlyLoggedOut.toggle()
try? FirebaseManager.shared.auth.signOut()
}
func readCodableUserWithMap() {
guard let uid = FirebaseManager.shared.auth.currentUser?.uid else {
self.errorMessage = "Could not find firebase uid"
print("FAILED TO FIND UID")
return
}
let userID = uid
let docRef = FirebaseManager.shared.firestore.collection("users").document(userID)
docRef.getDocument { (document, error) in
if let err = error {
print(err.localizedDescription)
return
}
if let doc = document {
let user = try! doc.data(as: User.self)
if let mappedField = user.socials {
mappedField.forEach { print([=11=].key, [=11=].value) }
}
}
}
}
}
readCodableUserWithMap() 应该初始化代表用户的可编码结构。见下文。
struct User: Identifiable, Codable {
@DocumentID var id: String?
var socials: [String: String]?
var uid, email, name, bio, profileImageUrl: String?
var numSocials, followers, following: Int?
}
手头的问题: 在我的仪表板视图中,我试图列出用户可以拥有的所有社交媒体。我无法为我的用户创建一个 ForEach 循环。
我愿意:
ForEach(vm.user?.socials.sorted(by: >), id: \.key) { key, value in
linkDisplay(social: key, handler: value)
.listRowSeparator(.hidden)
}.onDelete(perform: delete)
这给了我以下错误:
可选类型“[Dictionary
.Element] 的值?” (又名 'Optional<Array<(key: String, value: String)>>')必须解包为“[Dictionary .Element]”类型的值(又名 'Array<(key: String, value: String)>') 可选类型“[String : String]?”的值?必须解包以引用包装基类型“[String : String]”
的成员 'sorted'
我试过使用 ??但这不起作用,尽管我认为我做错了什么。强制展开是我尝试过的方法,但是当它是一个空字典时它使应用程序崩溃。
以防万一,这是数据库层次结构:firebase hierarchy
TLDR:我如何制作一个 ForEach 循环来列出我所有用户的媒体?
您有 vm.user
和 socials
作为选项。
ForEach
循环需要 non-optionals,所以
您可以尝试使用以下方法为 ForEach
循环解包。
if let user = vm.user, let socials = user.socials {
ForEach(socials.sorted(by: > ), id: \.key) { key, value in
linkDisplay(social: key, handler: value)
.listRowSeparator(.hidden)
}.onDelete(perform: delete)
}