[英]How to make ForEach loop for a Codable Swift Struct's Dictionary (based on Firestore map)
I am trying to do a ForEach loop that lists all of the social medias a user might have.我正在尝试做一个 ForEach 循环,列出用户可能拥有的所有社交媒体。 This would be on a scrollable list, the equivalent of music streaming apps have a list of all the songs you save in your library.这将在一个可滚动的列表上,相当于音乐流媒体应用程序有一个列表,列出了您保存在库中的所有歌曲。 The user's social medias list is in reality a dictionary .用户的社交媒体列表实际上是一本字典。
My MainViewModel class implements all of the Firebase functionality.我的 MainViewModel class 实现了 Firebase 的所有功能。 See below.见下文。
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($0.key, $0.value) }
}
}
}
}
}
readCodableUserWithMap() is supposed to initialize my codable struct, which represents a user. readCodableUserWithMap()应该初始化我的可编码结构,它代表一个用户。 See below.见下文。
struct User: Identifiable, Codable {
@DocumentID var id: String?
var socials: [String: String]?
var uid, email, name, bio, profileImageUrl: String?
var numSocials, followers, following: Int?
}
QUESTION AT HAND: In my Dashboard View, I am trying to have a list of all the social medias a user can have.手头的问题:在我的仪表板视图中,我试图列出用户可以拥有的所有社交媒体。 I can't manage to make a ForEach loop for my user.我无法为我的用户创建 ForEach 循环。
I do:我愿意:
ForEach(vm.user?.socials.sorted(by: >), id: \.key) { key, value in
linkDisplay(social: key, handler: value)
.listRowSeparator(.hidden)
}.onDelete(perform: delete)
This gives me the following errors:这给了我以下错误:
Value of optional type '[Dictionary<String, String>.Element]?'可选类型“[Dictionary<String, String>.Element] 的值?” (aka 'Optional<Array<(key: String, value: String)>>') must be unwrapped to a value of type '[Dictionary<String, String>.Element]' (aka 'Array<(key: String, value: String)>') (又名“Optional<Array<(key: String, value: String)>>”)必须解包为类型为“[Dictionary<String, String>.Element]”的值(又名“Array<(key: String,值:字符串)>')
Value of optional type '[String: String]?'可选类型“[String: String]?”的值? must be unwrapped to refer to member 'sorted' of wrapped base type '[String: String]'必须解包以引用包装基类型“[String: String]”的成员“sorted”
I have tried coalescing using??我试过合并使用?? but that doesn't work, although I assume I am doing something wrong.但这不起作用,尽管我认为我做错了什么。 Force-unwrapping is something I tried but it made the app crash when it was an empty dictionary.强制展开是我尝试过的方法,但是当它是一个空字典时它使应用程序崩溃。
Just in case, here is the database hierarchy: firebase hierarchy为了以防万一,这里是数据库层次结构: firebase hierarchy
TLDR: HOW can I make a ForEach loop to list all of my user's medias? TLDR:我如何制作一个 ForEach 循环来列出我所有用户的媒体?
You have both vm.user
and socials
as optionals.您将vm.user
和socials
都作为可选项。 The ForEach
loop requires non-optionals, so you could try the following approach to unwrap those for the ForEach
loop. ForEach
循环需要非可选值,因此您可以尝试使用以下方法为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)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.