簡體   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