swiftui - 在 SwiftUI 中实现登录导航
问题描述
这是我的要求:我想显示一个登录屏幕,通过网络请求执行身份验证,如果成功,则显示内容页面。
但是,我无法将两者结合起来——当网络请求在 LoginView 中完成时,我无法将流返回到 LoginControllerView 以导航到 ContentView。任何帮助将在这里不胜感激。
这是我的代码:
网络.swift
class ViewModel<T: Codable> : ObservableObject {
//@Published var calendar : IDCCalendar?
@Published var modelData : T?
func getData(url: URL, encoded: String, completion: (@escaping ()->()) ) {
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
print(encoded)
let encoder = JSONEncoder()
if let data = try? encoder.encode(encoded) {
request.httpBody = data
}
print("Request: \(request)")
URLSession.shared.dataTask(with: request) { data1, response, error in
if let error = error {
print("Request error: ", error)
return
}
guard let data1 = data1 else { return }
DispatchQueue.main.async {
let decoder = JSONDecoder()
print(String(decoding: data1, as: UTF8.self))
if let value = try? decoder.decode(T.self, from: data1)
{
self.modelData = value
completion()
print("Success!")
}
else {
print("Does not decode correctly")
}
}
}.resume()
}
LoginControllerView.swift
var body: some View {
Group {
if !userAuth.isLoggedin {
LoginView(userAuth: userAuth)
} else {
ContentView()
}
}
登录视图.swift
struct LoginView: View {
@EnvironmentObject var userAuth: UserAuth
@StateObject var viewModel = ViewModel<Login>()
var body: some View {
// Login Screen UI here
Button("Login") {
// Commenting out network request code out for now
/*
let url = URL(<URL goes here>)!
let encoded = <JSON String goes here>
let completion = {
if viewModel.modelData?.Status == 0 {
userAuth.isLoggedin = true
let login = viewModel.modelData!
let encoder = JSONEncoder()
if let data = try? encoder.encode(login) {
UserDefaults.standard.set(data, forKey: "LoginData")
}
}
viewModel.getData(url: url, encoded: encoded, completion: completion)
*/
// For test purposes, setting it to true, I want this to percolate back to
// LoginControllerView
userAuth.isLoggedin = true
}
UserAuth.swift
import Combine
class UserAuth: ObservableObject {
let didChange = PassthroughSubject<UserAuth,Never>()
// required to conform to protocol 'ObservableObject'
let willChange = PassthroughSubject<UserAuth,Never>()
func login() {
// login request... on success:
self.isLoggedin = true
}
var isLoggedin = false {
didSet {
didChange.send(self)
}
}
}
解决方案
推荐阅读
- mysql - 使用案例(或其他方法)使用查询中的值更改查询的 WHERE 子句
- sql - 从 UTC 时间计算特定时区的时间
- java - 在数据库操作上发布事件
- mysql - Mysql[5.7] 嵌套选择查询无法识别父表
- flutter - 如何在 Flutter Web 中访问应用程序版本?
- html - 为什么样式标签中的 CSS 胜过 main.css?
- ruby-on-rails - 即使我可以看到它们,也不能使用 rails 参数。具体charge_id
- android - libusb 在 Android 4.4.2 中同步传输时返回空包
- firebase - 使用缓存或快照侦听器优化从 Firestore 服务器读取的次数
- sql - 输出的 SQL 查询