iOS POST登录请求中如何根据API返回的StatusCode实现登录逻辑
Fixing iOS Login Flow Based on API StatusCode
Let's get your login logic working correctly by leveraging the StatusCode returned from your API. Here's how to adjust your code step by step:
1. Adjust the Login Button Callback Logic
The key is to check the StatusCode first before deciding whether to navigate to the dashboard or show an error. We'll also fix the loading animation timing to ensure it behaves properly across success and failure cases.
Here's the revised signInSegueToDashboard function:
@IBAction func signInSegueToDashboard(_ sender: Any) { // Start loading right when the user taps the button self.activityLoaderSignIn.startAnimating() APICallerPOST.shared.signInToAccount(username: "admin", password: "admin123") { [weak self] (result, error) in guard let self = self else { return } // Make sure we stop the loader no matter what happens defer { DispatchQueue.main.async { self.activityLoaderSignIn.stopAnimating() } } // Handle network or parsing errors first if let error = error { DispatchQueue.main.async { self.showErrorAlert(message: error.localizedDescription) } return } guard let result = result else { DispatchQueue.main.async { self.showErrorAlert(message: "An unknown error occurred") } return } // Safely extract the StatusCode from the API response guard let statusCode = result["StatusCode"] as? Int else { DispatchQueue.main.async { self.showErrorAlert(message: "Invalid response from server") } return } // Handle different status code cases switch statusCode { case 0: // Login success: Save user data and navigate to dashboard if let token = result["Result"]?["Token"] as? String { // Optional: Save token to Keychain (better than UserDefaults for sensitive data) UserDefaults.standard.set(token, forKey: "authToken") } DispatchQueue.main.async { guard let mainTabBarController = self.storyboard?.instantiateViewController(withIdentifier: "mainTabBarController") else { self.showErrorAlert(message: "Failed to load dashboard") return } mainTabBarController.modalPresentationStyle = .custom self.present(mainTabBarController, animated: true) } case 1: // Example: Invalid username/password DispatchQueue.main.async { self.showErrorAlert(message: "Wrong username or password") } case 2: // Example: Account locked DispatchQueue.main.async { self.showErrorAlert(message: "Your account has been locked. Please contact support.") } default: // Catch-all for any other error codes DispatchQueue.main.async { self.showErrorAlert(message: "Login failed with error code: \(statusCode)") } } } } // Helper function to show consistent error alerts private func showErrorAlert(message: String) { let alert = UIAlertController(title: "Login Failed", message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default)) present(alert, animated: true) }
2. Key Improvements Explained
- Loading Animation Fix: The loader starts immediately on button tap and stops in a
deferblock to guarantee it runs even if an error occurs. All UI updates useDispatchQueue.main.asyncsince network callbacks run on background threads. - StatusCode Handling: We use a
switchstatement to cleanly handle different status codes—this makes it easy to add more error cases later (like account verification required, etc.). - UI Thread Safety: All alert presentations and view controller navigation are wrapped in main thread calls to avoid UIKit crashes.
- Token Persistence: Optional but recommended—saving the auth token lets you use it for authenticated API requests later. For better security, consider using Keychain instead of UserDefaults for sensitive tokens.
3. Bonus: Use Codable for Cleaner Parsing
To avoid manual JSON type casting errors, define a Codable struct for your API response:
struct LoginResponse: Codable { let statusCode: Int let result: UserResult? enum CodingKeys: String, CodingKey { case statusCode = "StatusCode" case result = "Result" } } struct UserResult: Codable { let token: String let completeName: String let email: String // Add other user properties here matching the API response enum CodingKeys: String, CodingKey { case token = "Token" case completeName = "CompleteName" case email = "Email" } }
Then update your POST request function to parse with JSONDecoder:
let task = session.dataTask(with: request, completionHandler: { data, response, error in // ... existing error checks ... do { let loginResponse = try JSONDecoder().decode(LoginResponse.self, from: data) completion(loginResponse, nil) } catch let error { print(error.localizedDescription) completion(nil, error) } })
This makes your parsing safer and more maintainable.
内容的提问来源于stack exchange,提问作者Lis Tahirbegolli
相关产品推荐
相关产品推荐

