提问人:Vader20FF 提问时间:10/28/2021 最后编辑:Vader20FF 更新时间:10/28/2021 访问量:58
由于获取状态,ProgressView 无限期运行
ProgressView runs indefinitely because of fetching state
问:
我在为ProfileViewModel显示ProfileView中的所有数据时遇到异步数据获取问题。 我尝试了很多方法,结果要么无限期地加载 ProgressView 要么出现 nil 错误。 首先,我设置了 sessionStore(身份验证状态),将其从 View 的 .onAppear 传递给 ViewModel。然后我想将 firstName 和用户名从 Firebase 获取到我的 ProfileViewModel,这是我在 ProfileView init 中执行的 fetchData 函数中执行的。
ProfileViewModel:
@MainActor
class ProfileViewModel: ObservableObject {
@Published var sessionStore: SessionStore?
private let firestoreManager = FirestoreManager()
private let firebaseStorageManager = FirebaseStorageManager()
@Published var profile: Profile?
@Published var profilePicturePhotoURL: URL?
@Published var workouts: [IntervalWorkout]?
@Published var fetching: Bool = true
init(forPreviews: Bool) {
[...]
}
init() {
[...]
Task {
try await fetchData()
}
}
func setup(sessionStore: SessionStore) {
self.sessionStore = sessionStore
}
func fetchData() async throws {
if sessionStore != nil {
if sessionStore!.currentUser != nil {
print("Fetching Data")
let (firstname, username, birthDate, age, country, language, gender, email, profilePictureURL) = try await self.firestoreManager.fetchDataForProfileViewModel(userID: sessionStore!.currentUser!.uid)
self.profile = Profile(id: sessionStore!.currentUser!.uid, firstName: firstname, username: username, birthDate: birthDate, age: age, country: country, language: language, gender: gender, email: email, profilePictureURL: profilePictureURL)
print(self.profile!.firstName)
if profilePictureURL != nil {
self.firebaseStorageManager.getDownloadURLForImage(stringURL: profilePictureURL!, userID: sessionStore!.currentUser!.uid) { photoURL in
self.profilePicturePhotoURL = photoURL
print("Data fetched")
}
} else {
print("Data fetched - no profilePicture")
}
print("FETCHING: \(self.fetching)")
if self.profile != nil {
fetching = false
}
} else {
print("Data not fetched - no sessionStore.currentUser")
}
} else {
print("Data not fetched - no sessionStore")
}
}
func uploadPhoto(image: UIImage) {
[...]
}
func emailAddressChange(oldEmailAddress: String, password: String, newEmailAddress: String, completion: @escaping (() -> ())) {
[...]
}
func deleteUserData(completion: @escaping (() -> ())) {
[...]
}
}
配置文件视图:
struct ProfileView: View {
@ObservedObject private var profileViewModel = ProfileViewModel()
@EnvironmentObject private var sessionStore: SessionStore
@Environment(\.colorScheme) var colorScheme
@State private var image = UIImage()
@State private var shouldPresentAddActionSheet = false
@State private var shouldPresentImagePicker = false
@State private var shouldPresentCamera = false
@State private var shouldPresentSettings = false
@State private var tabSelection = 0
init(forPreviews: Bool) {
if forPreviews {
self.profileViewModel = ProfileViewModel(forPreviews: true)
}
}
var body: some View {
GeometryReader { geometry in
let screenWidth = geometry.size.width
let screenHeight = geometry.size.height
if !self.profileViewModel.fetching {
ScrollView(.vertical) {
HStack {
if profileViewModel.profilePicturePhotoURL != nil {
AsyncImage(url: profileViewModel.profilePicturePhotoURL!) { image in
[...]
} placeholder: {
[...]
}
} else {
[...]
}
Spacer(minLength: screenWidth * 0.05)
VStack {
HStack {
Text(profileViewModel.profile != nil ? profileViewModel.profile!.firstName : "Name")
[...]
}
}
.padding(.top, screenHeight * 0.02)
HStack {
Text(profileViewModel.profile != nil ? profileViewModel.profile!.username : "Username")
.foregroundColor(Color(uiColor: UIColor.lightGray))
Spacer()
}
Spacer()
}
}
.padding()
[...]
}
[...]
} else {
VStack {
Spacer()
HStack {
Spacer()
ProgressView("Loading user's data")
.progressViewStyle(RingProgressViewStyle())
Spacer()
}
Spacer()
}
}
}
.onAppear {
self.profileViewModel.setup(sessionStore: sessionStore)
}
}
}
控制台输出:
Data not fetched - no sessionStore
Data not fetched - no sessionStore
Fetching Data
Data not fetched - no sessionStore
Łukasz
Data fetched - no profilePicture
FETCHING: true
答: 暂无答案
评论