首页 > 解决方案 > 在 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)
    }

 }
}

标签: swiftui

解决方案


推荐阅读