数据库Integer类型数据为何在iOS端变为String?
id and emailConfirmed becoming Strings in Swift instead of Integers? This isn't exactly a "bug" in either your PHP or Swift code—it's a combination of how JSON serialization/deserialization works and how you're handling the data in Swift. Let's break this down:
1. What's happening on the PHP side
Your MySQL id and emailConfirmed are Integer types, and when you fetch them with mysqli_fetch_assoc(MYSQLI_ASSOC), PHP correctly returns them as integer values. When you run json_encode($returnArray), PHP by default serializes integers as JSON numeric types (e.g., "id": 123, "emailConfirmed": 1), so the JSON response is correct here.
2. The issue in your Swift code
When Swift's JSONSerialization.jsonObject parses the JSON, numeric values are converted to NSNumber (the Objective-C/Swift wrapper for numeric types). The problem comes in how you're accessing these values:
let confirmedUser = parsedJSON["emailConfirmed"] as! String
You're force-casting the NSNumber directly to a String, which causes Swift to implicitly convert the numeric value to its string representation. Similarly, when you save the entire parsedJSON (an NSDictionary) to UserDefaults, any NSNumber values will be treated as strings if you later access them with a string cast.
Fixes you can apply
Option 1: Correct the type casting in Swift
Instead of casting to String, cast the values to Int directly to preserve their numeric type:
// Handle emailConfirmed correctly guard let confirmedUser = parsedJSON["emailConfirmed"] as? Int else { print("Failed to parse email confirmation status") return } if confirmedUser == 1 { // Proceed with login flow UserDefaults.standard.set(parsedJSON, forKey: "parsedJSON") userInfo = UserDefaults.standard.object(forKey: "parsedJSON") as? NSDictionary self.activityIndicator.stopAnimating() self.performSegue(withIdentifier: "goToHomePage", sender: self) } else { // Show unconfirmed alert self.activityIndicator.stopAnimating() self.showAlert(alertTitle: "sorry", alertMessage: "please complete your registration process first, please check your email", actionTitle: "OK") } // For id, use the same approach when accessing it later if let userId = userInfo?["id"] as? Int { // Use the integer ID as needed }
Option 2: Explicitly enforce numeric types in PHP (optional)
While not strictly necessary for your case, you can add the JSON_NUMERIC_CHECK flag to json_encode to eliminate any edge cases where PHP might accidentally serialize numbers as strings:
echo json_encode($returnArray, JSON_NUMERIC_CHECK);
Bonus: Avoid force casting in Swift
Force casting (as!) can lead to crashes if the JSON structure changes unexpectedly. Using optional binding (like the guard let example above) makes your code more robust and easier to debug.
内容的提问来源于stack exchange,提问作者Agung

