iOS Swift中URL Session以form-data提交手机号参数问题求助
Fixing Multipart Form-Data Submission with URLSession in Swift
Let's break down what's going wrong in your current code and fix it step by step:
Key Issues in Your Code
- Incorrect Content-Type Header:
- You have a typo (
Contet-Typeinstead ofContent-Type). - The header value format is wrong—it should use a semicolon to separate the boundary, not a colon:
multipart/form-data; boundary=\(boundary).
- You have a typo (
- Wrong HTTP Body Format:
- You're using
NSKeyedArchiverandJSONSerialization, which produce plist and JSON data respectively. Neither is the correct format for multipart form-data.
- You're using
- Unnecessary Accept Header:
- Setting
Accepttomultipart/form-datais probably unnecessary unless the API explicitly returns form-data. Most APIs return JSON, so useapplication/jsoninstead.
- Setting
Corrected Code
Here's how to properly construct and send multipart form-data:
func registerService() { print("register tapped") // Guard against nil mobile number to avoid crashes guard let mobileNumber = mobileNumber else { print("Mobile number is nil") return } let parameters: [String: String] = ["mobile": mobileNumber] guard let url = URL(string: "http://54.251.198.30/api/user/login") else { print("Invalid URL") return } var req = URLRequest(url: url) req.httpMethod = "POST" let boundary = "Boundary-\(UUID().uuidString)" // Fix Content-Type header with correct syntax req.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") // Set Accept header to expect JSON response (adjust if your API uses a different format) req.setValue("application/json", forHTTPHeaderField: "Accept") // Build the proper multipart form-data body let httpBody = createMultipartFormData(with: parameters, boundary: boundary) req.httpBody = httpBody let session = URLSession.shared session.dataTask(with: req) { data, response, error in // Handle request errors first if let error = error { print("Request error: \(error.localizedDescription)") return } // Log the status code for debugging if let httpResponse = response as? HTTPURLResponse { print("Status code: \(httpResponse.statusCode)") } // Ensure we have data to parse guard let data = data else { print("No data received from server") return } // Try decoding the response do { let jsonResponse = try JSONDecoder().decode(LoginBase.self, from: data) print(jsonResponse) } catch { print("Decoding error: \(error.localizedDescription)") // Print raw response string to debug mismatched structs if let rawResponse = String(data: data, encoding: .utf8) { print("Raw server response: \(rawResponse)") } } }.resume() } // Helper function to construct multipart form-data body private func createMultipartFormData(with parameters: [String: String], boundary: String) -> Data { let body = NSMutableData() for (key, value) in parameters { // Add boundary separator body.append("--\(boundary)\r\n".data(using: .utf8)!) // Specify field name in Content-Disposition header body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: .utf8)!) // Append the field value body.append("\(value)\r\n".data(using: .utf8)!) } // Add closing boundary to end the form-data body.append("--\(boundary)--\r\n".data(using: .utf8)!) return body as Data }
Explanation of Changes
- Guard Clauses: Added checks for nil mobile number and invalid URL to prevent unexpected crashes.
- Corrected Headers: Fixed the Content-Type header typo and format, and set the Accept header to expect JSON (adjust this if your API returns a different response type).
- Multipart Body Builder: The
createMultipartFormDatahelper constructs the proper form-data format by:- Adding boundary strings to separate each field.
- Including
Content-Dispositionheaders to define each field's name. - Appending the field values and closing the form with a final boundary.
- Improved Error Handling: Added detailed error logging for request issues, missing data, and decoding failures, plus raw response output to help debug mismatched response structures.
Notes
- If you need to add file uploads later, you can extend the helper function to include file data with appropriate
Content-Typeheaders for the file type (e.g.,image/jpegfor photos). - Ensure your
LoginBasestruct exactly matches the structure of the API's JSON response to avoid decoding errors.
内容的提问来源于stack exchange,提问作者Al Mustakim
相关产品推荐
相关产品推荐

