[英]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
,將用戶發送到下一個視圖。
需要考慮的一些事項:
Back
按鈕 go 返回初始登錄屏幕,您可能根本不想使用NavigationLink
- 您可能只想有條件地顯示一個視圖:if loginManager.isLoggedIn {
LoggedInView()
} else {
LoginForm()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.