繁体   English   中英

成功 http 请求登录后直接到 swiftUI 中的新视图

[英]direct to new view in swiftUI after successful http request login

我一直在使用 php 和 mysql 数据库来创建一个简单的用户注册和登录系统。 登录 php 文件有效,我已将其连接到 Xcode 中的项目。 但是,我不太确定如何确保这个 function 在单击登录按钮时运行,并且只有在登录成功后才会移动到下一个视图。

这是我的 swift 代码:

import SwiftUI


struct loginview_Previews: PreviewProvider {
static var previews: some View {
    loginview()
}
}

struct loginview: View {

// variables and fields

@State private var username : String  = ""
@State private var password : String = ""

let databaseurl = "http://localhost/login.php"

var body: some View {
        
        // put into a navigation view
        
        NavigationView{
            
            // form to enter details
            
            Form{
                
                // start section with a header for info
                
                Section(header: Text("enter your details to log in !")){
                    
                    // username field
                    
                    TextField("username", text: $username)
                        
                        .font(.headline)
                        .frame(width: 350.0)
                        .foregroundColor(.white)
                        .padding(.all, 20.0)
                        .cornerRadius(9.0)
                        .preferredColorScheme(.dark)
                    
                    TextField("password", text: $password)
                        
                        .font(.headline)
                        .frame(width: 350.0)
                        .foregroundColor(.white)
                        .padding(.all, 20.0)
                        .cornerRadius(9.0)
                        .preferredColorScheme(.dark)
                    
                } .textCase(nil)  // make header lowercase
                
                Section{
                    NavigationLink(destination: homepage()){  // link to home page view
                        
                        Text("submit")
                            
                            .foregroundColor(.white)
                            .fontWeight(.heavy)
                            .font(.system(size: 22))
                            .padding(.all, 20.0)
                            .frame(width: 175.0)
                            .preferredColorScheme(.dark)
                        
                    }
                }
                
                // button is unclickable if textfields are empty
                
                .disabled(username.isEmpty)
                .disabled(password.isEmpty)
            }
            
            .navigationBarTitle("log in") // title of form
        }
    }

//

func logindatabase(){
            
            // create NSURL - an object initialized with URLString
            
            if var requesturl = URLComponents(string: databaseurl) {
                
                requesturl.query = "username=\(username)&password=\(password)"
                print(requesturl)
                
                guard let url = requesturl.url else { return }
                
                let task = URLSession.shared.dataTask(with: url) { data, response, error in

                    
                    if error != nil {
                        print("error is \(String(describing: error))")
                        return
                    }
                    
                    // parse the response
                    
                    do {
                        // convert response to NSDictionary
                        
                        let myJSON = try JSONSerialization.jsonObject(with: data! , options: .mutableContainers) as? NSDictionary
                        
                        if let parseJSON = myJSON {
                            // create a string & get the json response
                            
                            guard let message = parseJSON["message"] as? String else { return }
                            
                            // print the response
                            
                            print(message)
                            
                        }
                        
                    } catch {
                        print(error)
                    }
                }
                task.resume()
            }

        }
 }

这是我的 login.php 文件:

<?php

//include the db operation file
require_once 'dboperations.php' ;

// create a response array
$response = array();

if ($_SERVER['REQUEST_METHOD'] == 'GET') {

    if (isset($_GET['username']) && isset($_GET['password'])) {

        $db = new dboperation();

        if ($db->userlogin($_GET['username'], $_GET['password'])) {
            $response['error'] = false;
            $response['user'] = $db->displayuser($_GET['username']);
        } else {
            $response['error'] = true;
            $response['message'] = 'invalid username or password';
        }

    } else {
        $response['error'] = true;
        $response['message'] = 'parameters are missing';
    }

} else {
    $response['error'] = true;
    $response['message'] = "Request not allowed";
}

echo json_encode($response);

这确实有效。

这是您正在谈论的一个非常简单的版本:

class LoginManager : ObservableObject {
    @Published var isLoggedIn = false
    
    func doLogin(username: String, password: String) {
        //in here, you'll do your network call
        //I've mocked it with a simple async call for now
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            //set this once you get the correct response from your server
            //this triggers isActive on the NavigationLink below
            self.isLoggedIn = true
        }
    }
}

struct ContentView : View {
    @ObservedObject private var loginManager = LoginManager()
    
    @State var username = ""
    @State var password = ""
    
    var body: some View {
        NavigationView {
            Button(action: {
                loginManager.doLogin(username: username, password: password)
            }) {
                //Login fields...
                Text("Log me in")
            }.overlay(
                NavigationLink(destination: LoggedInView(), isActive: $loginManager.isLoggedIn) {
                    EmptyView()
                }
            )
        }
    }
}

struct LoggedInView : View {
    var body: some View {
        Text("Logged in")
    }
}

请注意,我使用Button来代替NavigationLink进行初始操作。 然后,调用一个名为doLogin的 function,它是一个 @Published 属性,表示用户是否已登录。

如果isLoggedIn为真,则触发NavigationLink上的isActive ,将用户发送到下一个视图。

需要考虑的一些事项:

  1. 在现实世界中,您永远不应该通过 GET 请求发送用户名/密码——这太不安全了
  2. 如果您不希望用户只能使用Back按钮 go 返回初始登录屏幕,您可能根本不想使用NavigationLink - 您可能只想有条件地显示一个视图:
if loginManager.isLoggedIn {
  LoggedInView()
} else {
  LoginForm()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM