You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift应用对接MySQL数据库实现登录功能技术求助

How to Connect Your Swift Login System to a MySQL-Backed Website

Hey there! I see you're trying to hook up your Swift app's login system to a MySQL-backed website, and hitting a wall—totally get how frustrating that can be. Let's break this down because the key issue here is probably that you're trying to connect directly to MySQL from Swift, which isn't just impractical, it's a huge security risk. Here's a step-by-step, industry-standard solution:

1. The Critical First Rule: Never Connect Swift Directly to MySQL

Your Swift app should never talk directly to your MySQL database. Doing so would force you to embed sensitive database credentials (like username/password) in your app, which anyone can reverse-engineer. Instead, you need a middle layer: a simple REST API on your website that handles the MySQL interaction, and your Swift app sends HTTP requests to this API.

2. Build a Simple Login API (Example with PHP)

If your website runs on PHP (a common pairing with MySQL), create a file like login.php on your server with this code:

<?php
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *"); // Restrict this to your app's domain in production

// Get POST data from the Swift app
$input = json_decode(file_get_contents('php://input'), true);
$username = $input['username'] ?? '';
$password = $input['password'] ?? '';

// Connect to your MySQL database (replace with your own credentials)
$conn = new mysqli('your-db-host', 'db-username', 'db-password', 'db-name');
if ($conn->connect_error) {
    echo json_encode(['success' => false, 'message' => 'Database connection failed']);
    exit();
}

// Use prepared statements to avoid SQL injection attacks
$stmt = $conn->prepare("SELECT id, password FROM users WHERE username = ?");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();

if ($user = $result->fetch_assoc()) {
    // Verify password (your DB should store hashed passwords, not plain text!)
    if (password_verify($password, $user['password'])) {
        echo json_encode(['success' => true, 'user_id' => $user['id']]);
    } else {
        echo json_encode(['success' => false, 'message' => 'Invalid password']);
    }
} else {
    echo json_encode(['success' => false, 'message' => 'User not found']);
}

$stmt->close();
$conn->close();
?>

Important notes for this API:

  • Always use prepared statements to block SQL injection attacks.
  • Never store plain-text passwords in MySQL—use password_hash() when creating users, and password_verify() to check them (as shown above).
  • In production, replace Access-Control-Allow-Origin: * with your app's specific domain to prevent unauthorized cross-site requests.
  • Serve the API over HTTPS to encrypt data in transit (most hosts offer free SSL certificates via Let's Encrypt).

3. Update Your Swift Code to Call the API

Modify your SignInViewController to send a POST request to your new API instead of trying to connect to MySQL directly. Here's how to do it with URLSession:

import UIKit

class SignInViewController: UIViewController, UITextFieldDelegate {
    @IBOutlet var UsernameTextField: UITextField!
    @IBOutlet var PasswordTextField: UITextField!
    @IBOutlet var LogInButton: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Set up text field delegates
        UsernameTextField.delegate = self
        PasswordTextField.delegate = self
    }
    
    @IBAction func logInTapped(_ sender: UIButton) {
        // Validate input first
        guard let username = UsernameTextField.text?.trimmingCharacters(in: .whitespaces), !username.isEmpty,
              let password = PasswordTextField.text?.trimmingCharacters(in: .whitespaces), !password.isEmpty else {
            showAlert(title: "Oops", message: "Please enter both username and password")
            return
        }
        
        // Prepare login data to send to API
        let loginPayload = ["username": username, "password": password]
        guard let jsonData = try? JSONSerialization.data(withJSONObject: loginPayload) else {
            showAlert(title: "Error", message: "Failed to prepare request")
            return
        }
        
        // Configure API request
        guard let apiUrl = URL(string: "https://your-website-domain.com/login.php") else {
            showAlert(title: "Error", message: "Invalid API URL")
            return
        }
        
        var request = URLRequest(url: apiUrl)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = jsonData
        
        // Send request to API
        let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
            // Switch back to main thread to update UI
            DispatchQueue.main.async {
                if let error = error {
                    self?.showAlert(title: "Network Error", message: error.localizedDescription)
                    return
                }
                
                guard let responseData = data else {
                    self?.showAlert(title: "Error", message: "No response from server")
                    return
                }
                
                // Parse API response
                do {
                    if let responseDict = try JSONSerialization.jsonObject(with: responseData, options: []) as? [String: Any] {
                        let isLoginSuccess = responseDict["success"] as? Bool ?? false
                        if isLoginSuccess {
                            let userId = responseDict["user_id"] as? Int
                            self?.handleSuccessfulLogin(userId: userId)
                        } else {
                            let errorMessage = responseDict["message"] as? String ?? "Login failed"
                            self?.showAlert(title: "Login Failed", message: errorMessage)
                        }
                    }
                } catch {
                    self?.showAlert(title: "Error", message: "Failed to parse server response")
                }
            }
        }
        task.resume()
    }
    
    // Helper to show alert dialogs
    private func showAlert(title: String, message: String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
    }
    
    // Handle post-login flow (navigate to main screen, save session, etc.)
    private func handleSuccessfulLogin(userId: Int?) {
        showAlert(title: "Success!", message: "You're logged in as user #\(userId ?? 0)")
        // Add code here to navigate to your app's main screen
    }
    
    // Optional: Hide keyboard when return key is tapped
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
    
    // Optional: Hide keyboard when tapping outside text fields
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        view.endEditing(true)
    }
}

4. Key Best Practices for Security & Reliability

  • Use Token-Based Auth: After a successful login, have your API return a JWT (JSON Web Token) instead of just a user ID. Store this token in Apple's Keychain (not UserDefaults) for secure persistent sessions, and send it in subsequent API requests to authenticate the user.
  • Add Rate Limiting: Configure your server to limit login attempts from a single IP to prevent brute-force attacks.
  • Validate Input Everywhere: Both your Swift app and API should validate user input (e.g., check for valid email formats, block special characters that could break queries).
  • Test the API First: Use tools like Postman or curl to test your login.php endpoint directly before integrating it into Swift—this helps you debug MySQL or server issues without worrying about Swift code.

内容的提问来源于stack exchange,提问作者moe safar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:03:36