我是SwiftUI和Firebase的新手,正在尝试创建一个预算应用程序。我无法保存用户数据。我使用的是SwiftUI(不是Storyboard),我还有AppDelegate和SceneDelegate。
应用程序的工作方式是要求用户创建配置文件(电子邮件和密码),然后在FireBase中创建用户。然后,它将用户重定向到需要以下数据的第二个屏幕(见图):
我的问题是:
我正在网上搜索一个解决方案已经有几天了,但是网上的所有东西要么是使用Storyboard要么是很旧的Swift版本。此外,我已经创建了用户,但我不知道如何将屏幕上的数据与创建的用户关联起来。
下面是上图屏幕的代码:
struct RegistrationProfileDataView: View {
//@Binding var show : Bool
@State var firstName = ""
@State var lastName = ""
@State var age = ""
@State var location = ""
@State var picker = false
@State var loading = false
@State var imagedata : Data = .init(count: 0)
@State var alert = false
var body: some View {
VStack(alignment: .leading) {
Group {
Group {
Text("Welcome")
.font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/)
Text("Please finish your registration")
Button(action: {
self.picker.toggle()
}) {
if self.imagedata.count == 0 {
Image("ChangeProfPhoto").resizable().frame(width: 109, height: 109)
}
else {
Image(uiImage: UIImage(data: self.imagedata)!).resizable().renderingMode(.original).frame(width: 109, height: 109).clipShape(Circle())
}
}
.padding(.bottom, 20)
.padding(.top, 20)
}
.padding(.leading, 25)
TextField("First Name", text: self.$firstName)
.padding(.leading, 20)
.frame(minWidth: 0, maxWidth: .infinity)
.frame(height: 45.0)
.overlay(Capsule().stroke(Color.lightGray, lineWidth: 1))
.padding(.horizontal, 25)
TextField("Last Name", text: self.$lastName)
.padding(.leading, 20)
.frame(minWidth: 0, maxWidth: .infinity)
.frame(height: 45.0)
.overlay(Capsule().stroke(Color.lightGray, lineWidth: 1))
.padding(.horizontal, 25)
TextField("Age", text: self.$age)
.padding(.leading, 20)
.frame(minWidth: 0, maxWidth: .infinity)
.frame(height: 45.0)
.overlay(Capsule().stroke(Color.lightGray, lineWidth: 1))
.padding(.horizontal, 25)
TextField("City", text: self.$location)
.padding(.leading, 20)
.frame(minWidth: 0, maxWidth: .infinity)
.frame(height: 45.0)
.overlay(Capsule().stroke(Color.lightGray, lineWidth: 1))
.padding(.horizontal, 25)
Button(action: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Action@*/{}/*@END_MENU_TOKEN@*/) {
Text("Link a Bank Account")
}
.frame(minWidth: 0, maxWidth: .infinity)
.frame(height: 45.0)
.background(Capsule().fill(Color.lightGray))
.padding(.horizontal, 25.0)
.padding(.bottom, 15.0)
}
Spacer()
Group {
Button(action: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Action@*/{}/*@END_MENU_TOKEN@*/) {
Text("Finish")
.foregroundColor(.white)
.padding()
}
.frame(minWidth: 0, maxWidth: .infinity)
.frame(height: 45.0)
.background(Capsule().fill(Color.blue))
.padding(.horizontal, 25.0)
.padding(.bottom, 15.0)
.shadow(color: ColorManager.blueButton.opacity(0.2), radius: 10, x: 2.0, y: 2.0)
}
}
}
}
Firebase文档非常好,都是现代的Swift代码。它并不真正依赖UI代码(SwiftUI或Storyboards)。
关于SwiftUI,一般来说,您可能希望在视图之外进行网络调用,可能是在ObservableObject中:
class FirebaseManager : ObservableObject {
func uploadImage(imageData: Data) {
//do upload
}
}
您可以通过执行以下操作将其存储在视图中:
@StateObject private var firebaseManager = FirebaseManager()
要上传一个映像,您可以执行如下操作(这几乎直接取自Firebase文档--https://Firebase.google.com/docs/storage/ios/upload-files):
// Create a reference to the file you want to upload
let profileImageRef = storageRef.child("images/\(userID)/rivers.jpg")
// Upload the file to the path "images/rivers.jpg"
let uploadTask = profileImageRef.putData(data, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
// Uh-oh, an error occurred!
return
}
// Metadata contains file metadata such as size, content-type.
let size = metadata.size
// You can also access to download URL after upload.
profileImageRef.downloadURL { (url, error) in
guard let downloadURL = url else {
// Uh-oh, an error occurred!
return
}
}
}
请注意,在第一行中,我使用了userid
--您可以通过执行以下操作获得对登录用户的引用:
guard let userID = Auth.auth().currentUser?.uid else {
return
}
最后,关于“如何将照片和其他数据(年龄、城市等)关联到创建的用户”的问题,您需要选择Firestore或Realtime Database。在现代Swift的https://firebase.google.com/docs中都有很好的文档。
在firebaseManager
中创建一个函数来上传数据,并确保将其与配置文件图像的用户ID相关联(如上文所述)。