[英]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.