我已经开始努力使用SwiftUI将本机IOS应用程序替换为Web应用程序,或者至少与Web应用程序一起使用。
将脚趾浸入水中并在此处使用代码形式的答案后,我已经能够成功创建一个登录屏幕,该登录屏幕通过url连接到API并返回JSON。成功登录后,我便可以进行身份验证并进入下一个视图。这就是我现在停留的地方,很可能是由于我要处理的信息量大和/或经验不足。
登录后,我需要显示一个菜单。该菜单将取决于用户有权访问的内容。我已经编写了API,并且可以正常工作。我不理解并且遇到麻烦的是如何进行下一个API调用。
BaseView.swift
import SwiftUI
struct BaseView : View {
@EnvironmentObject var viewRouter: ViewRouter
var body: some View {
VStack {
if viewRouter.currentPage == "view1" {
FirstView()
} else if viewRouter.currentPage == "view2" {
SecondView()
.transition(.scale)
}
}
} }
#if DEBUG struct MotherView_Previews : PreviewProvider {
static var previews: some View {
BaseView().environmentObject(ViewRouter())
} }
#endif
ViewRouter.swift
import Foundation
import Combine
import SwiftUI
class ViewRouter: ObservableObject {
let objectWillChange = PassthroughSubject<ViewRouter,Never>()
var currentPage: String = "view1" {
didSet {
withAnimation() {
objectWillChange.send(self)
}
}
}
}
FirstView.swift
import SwiftUI
struct FirstView : View {
@EnvironmentObject var viewRouter: ViewRouter
@State var username: String = ""
@State var password: String = ""
@State var authenticationDidFail: Bool = false
@State var authenticationDidSucceed: Bool = false
@State var selection: Bool = false
@ObservedObject var manager = HttpAuth()
var body: some View {
NavigationView{
ZStack{
VStack {
WelcomeText()
UsernameTextField(username: $username)
PasswordSecureField(password: $password)
if authenticationDidFail {
Text("Information not correct. Try again.")
.offset(y: -10)
.foregroundColor(.red)
}
NavigationLink(destination: SecondView(), isActive: self.$selection){
EmptyView()
}
Button(action: {
self.manager.postAuth(username: self.username, password: self.password)
self.viewRouter.currentPage = "view2"
}) {
LoginButtonContent()
}
}
.padding()
/* if authenticationDidSucceed {
Text("Login succeeded!")
.font(.headline)
.frame(width: 250, height: 80)
.background(Color.green)
.cornerRadius(20.0)
.foregroundColor(.white)
.animation(Animation.default)
}*/
if self.manager.authenticated{
Text("Logged in!")
//.font(.headline)
.frame(width: 250, height: 80)
.background(Color.green)
.foregroundColor(.white)
.animation(Animation.default)
//NextButtonContent()
SecondView()
}
}
}
}
}
#if DEBUG
struct FirstView_Previews : PreviewProvider {
static var previews: some View {
FirstView().environmentObject(ViewRouter())
}
}
#endif
struct NextButtonContent : View {
var body: some View {
return Text("Next")
.foregroundColor(.white)
.frame(width: 200, height: 50)
.background(Color.blue)
.cornerRadius(15)
.padding(.top, 50)
}
}
struct EmptyView : View {
var body: some View {
Text("")
}
}
SecondView.swift
import SwiftUI
struct SecondView : View {
@EnvironmentObject var viewRouter: ViewRouter
@ObservedObject var manager = HttpAuth()
var body: some View {
VStack {
Spacer(minLength: 50.0)
Text("Hello")
Button(action: {self.viewRouter.currentPage = "view1"
// self.manager.postMenu(username: self.username, password: self.password)
}) {
BackButtonContent()
}
}
}
}
#if DEBUG
struct SecondView_Previews : PreviewProvider {
static var previews: some View {
SecondView().environmentObject(ViewRouter())
}
}
#endif
struct BackButtonContent : View {
var body: some View {
return Text("Back")
.foregroundColor(.white)
.frame(width: 200, height: 50)
.background(Color.blue)
.cornerRadius(15)
.padding(.top, 50)
}
}
在SecondView.swift上,我尝试通过使用Binding(@Binding var username:String)进行声明来重用用户名和密码变量,但是随后我发现到处都是错误,包括SecondView.type不可转换。
我在这里走错了路吗?还是需要将这些变量存储在EnvironmentObject中?
SecondView应该通过HttpAuth类下的postMenu进行API调用(您可以在其中看到注释),然后返回JSON(我假定为列表)。这是我要问的问题,如何将这些变量重用于其他视图/调用,然后在以后使用?