Bird
Raised Fist0
iOS Swiftmobile~20 mins

POST request with JSON body in iOS Swift - Mini App: Build & Ship

Choose your learning style10 modes available
Build: PostRequestScreen
This screen sends a POST request with a JSON body to a test API and shows the response.
Target UI
-------------------------
| Post Request Screen    |
|-----------------------|
| [Send POST Request]    |
|                       |
| Response:             |
| <response text here>  |
-------------------------
Add a button labeled 'Send POST Request'.
When tapped, send a POST request to https://jsonplaceholder.typicode.com/posts.
The POST request must include a JSON body with keys: title, body, userId.
Show the response JSON as a string below the button.
Handle errors by showing an error message in the response area.
Starter Code
iOS Swift
import SwiftUI

struct PostRequestScreen: View {
    @State private var responseText = ""

    var body: some View {
        VStack(spacing: 20) {
            Text("Post Request Screen")
                .font(.title)

            Button("Send POST Request") {
                // TODO: Add POST request code here
            }
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(8)

            Text("Response:")
                .font(.headline)
                .frame(maxWidth: .infinity, alignment: .leading)

            ScrollView {
                Text(responseText)
                    .font(.body)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding()
                    .background(Color.gray.opacity(0.1))
                    .cornerRadius(8)
            }
            Spacer()
        }
        .padding()
    }
}

struct PostRequestScreen_Previews: PreviewProvider {
    static var previews: some View {
        PostRequestScreen()
    }
}
Task 1
Task 2
Task 3
Task 4
Task 5
Task 6
Solution
iOS Swift
import SwiftUI

struct PostRequestScreen: View {
    @State private var responseText = ""

    var body: some View {
        VStack(spacing: 20) {
            Text("Post Request Screen")
                .font(.title)

            Button("Send POST Request") {
                sendPostRequest()
            }
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(8)

            Text("Response:")
                .font(.headline)
                .frame(maxWidth: .infinity, alignment: .leading)

            ScrollView {
                Text(responseText)
                    .font(.body)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding()
                    .background(Color.gray.opacity(0.1))
                    .cornerRadius(8)
            }
            Spacer()
        }
        .padding()
    }

    func sendPostRequest() {
        guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else {
            responseText = "Invalid URL"
            return
        }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        let jsonBody: [String: Any] = ["title": "foo", "body": "bar", "userId": 1]

        do {
            let jsonData = try JSONSerialization.data(withJSONObject: jsonBody)
            request.httpBody = jsonData
        } catch {
            responseText = "Failed to encode JSON body"
            return
        }

        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            DispatchQueue.main.async {
                if let error = error {
                    responseText = "Error: \(error.localizedDescription)"
                    return
                }

                guard let data = data else {
                    responseText = "No data received"
                    return
                }

                if let jsonString = String(data: data, encoding: .utf8) {
                    responseText = jsonString
                } else {
                    responseText = "Failed to decode response"
                }
            }
        }
        task.resume()
    }
}

struct PostRequestScreen_Previews: PreviewProvider {
    static var previews: some View {
        PostRequestScreen()
    }
}

This solution creates a SwiftUI screen with a button labeled 'Send POST Request'. When the button is tapped, it calls sendPostRequest().

Inside sendPostRequest(), it builds a URLRequest with the POST method and sets the Content-Type header to application/json. It creates a dictionary with the required keys and converts it to JSON data.

The request is sent asynchronously using URLSession.shared.dataTask. When the response arrives, it updates the responseText state on the main thread to show the JSON response or an error message.

This approach keeps the UI responsive and clearly shows the server response below the button.

Final Result
Completed Screen
-------------------------
| Post Request Screen    |
|-----------------------|
| [Send POST Request]    |
|                       |
| Response:             |
| {                     |
|   "id": 101,         |
|   "title": "foo",   |
|   "body": "bar",    |
|   "userId": 1        |
| }                     |
-------------------------
User taps 'Send POST Request' button.
App sends POST request with JSON body to the API.
Response JSON is displayed below the button.
If error occurs, error message is shown instead.
Stretch Goal
Add a loading indicator that shows while the POST request is in progress.
💡 Hint
Use a @State Boolean to track loading state and show a ProgressView when true.

Practice

(1/5)
1. What is the main purpose of a POST request with a JSON body in iOS Swift networking?
easy
A. To send data to a server, usually to create or update resources
B. To retrieve data from a server without sending any data
C. To delete data from a server
D. To open a WebSocket connection

Solution

  1. Step 1: Understand HTTP methods

    POST requests are used to send data to a server, often to create or update something.
  2. Step 2: Recognize JSON role

    JSON is a format to structure the data sent in the body of the POST request.
  3. Final Answer:

    To send data to a server, usually to create or update resources -> Option A
  4. Quick Check:

    POST sends data = A [OK]
Hint: POST means send data to server, not just get [OK]
Common Mistakes:
  • Confusing POST with GET method
  • Thinking POST is for deleting data
  • Ignoring the role of JSON in the body
2. Which Swift code snippet correctly sets the HTTP method to POST and adds a JSON Content-Type header?
easy
A. request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type")
B. request.method = "POST" request.addHeader("Content-Type", value: "application/json")
C. request.httpMethod = POST request.setHeader("Content-Type", "application/json")
D. request.method = POST request.setValue("json", forHTTPHeaderField: "Content-Type")

Solution

  1. Step 1: Set HTTP method correctly

    The property to set HTTP method in URLRequest is httpMethod and it expects a String like "POST".
  2. Step 2: Add JSON Content-Type header properly

    Use setValue(_:forHTTPHeaderField:) with "application/json" for the "Content-Type" header.
  3. Final Answer:

    request.httpMethod = "POST"\nrequest.setValue("application/json", forHTTPHeaderField: "Content-Type") -> Option A
  4. Quick Check:

    Correct method and header syntax = A [OK]
Hint: Use request.httpMethod and setValue for headers [OK]
Common Mistakes:
  • Using wrong property names like method or setHeader
  • Forgetting quotes around "POST"
  • Using incorrect header field names or values
3. Given the Swift code below, what will be the printed output?
let url = URL(string: "https://example.com/api")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let jsonBody = ["name": "Alice", "age": 30] as [String : Any]
request.httpBody = try? JSONSerialization.data(withJSONObject: jsonBody)
print(String(data: request.httpBody!, encoding: .utf8)!)
medium
A. ["name": "Alice", "age": 30]
B. {"name":"Alice","age":30}
C. Optional({"name":"Alice","age":30})
D. nil

Solution

  1. Step 1: Serialize dictionary to JSON data

    JSONSerialization.data converts the dictionary to JSON data bytes representing {"name":"Alice","age":30}.
  2. Step 2: Convert data to UTF-8 string

    Printing the data as UTF-8 string shows the JSON string without brackets or Optional wrapper.
  3. Final Answer:

    {"name":"Alice","age":30} -> Option B
  4. Quick Check:

    JSONSerialization outputs JSON string = B [OK]
Hint: JSONSerialization outputs JSON string, not Swift dictionary syntax [OK]
Common Mistakes:
  • Expecting Swift dictionary syntax instead of JSON string
  • Printing Optional wrapper
  • Forgetting to unwrap data or encoding
4. Identify the error in this Swift code for sending a POST request with JSON body:
var request = URLRequest(url: URL(string: "https://api.example.com")!)
request.httpMethod = "POST"
let json = ["key": "value"]
request.httpBody = try? JSONSerialization.jsonObject(with: json)
medium
A. httpMethod should be lowercase "post"
B. Missing setting Content-Type header to application/json
C. Using JSONSerialization.jsonObject instead of data(withJSONObject:)
D. URLRequest initialization is incorrect

Solution

  1. Step 1: Check JSON serialization method

    jsonObject(with:) parses JSON data to object; to create JSON data from object, use data(withJSONObject:).
  2. Step 2: Confirm other parts

    Content-Type header missing is an issue but not the main error causing failure here.
  3. Final Answer:

    Using JSONSerialization.jsonObject instead of data(withJSONObject:) -> Option C
  4. Quick Check:

    Wrong JSON method used = D [OK]
Hint: Use data(withJSONObject:) to create JSON data, not jsonObject(with:) [OK]
Common Mistakes:
  • Confusing jsonObject(with:) with data(withJSONObject:)
  • Forgetting Content-Type header
  • Incorrect URLRequest initialization
5. You want to send a POST request with a JSON body containing user info, but only include the "email" field if it is not empty. Which Swift code snippet correctly creates the JSON body for this conditional inclusion?
hard
A. var jsonBody = ["name": "Bob", "email": email] if !email.isEmpty { jsonBody.removeValue(forKey: "email") } request.httpBody = try? JSONSerialization.data(withJSONObject: jsonBody)
B. let jsonBody = ["name": "Bob", "email": email.isEmpty ? nil : email] request.httpBody = try? JSONSerialization.data(withJSONObject: jsonBody)
C. let jsonBody = ["name": "Bob"] if email != "" { jsonBody["email"] = email } request.httpBody = try? JSONSerialization.data(withJSONObject: jsonBody)
D. var jsonBody = ["name": "Bob"] if !email.isEmpty { jsonBody["email"] = email } request.httpBody = try? JSONSerialization.data(withJSONObject: jsonBody)

Solution

  1. Step 1: Understand conditional dictionary update

    var jsonBody = ["name": "Bob"] if !email.isEmpty { jsonBody["email"] = email } request.httpBody = try? JSONSerialization.data(withJSONObject: jsonBody) creates a mutable dictionary and adds "email" only if not empty, which is correct.
  2. Step 2: Check other options for errors

    let jsonBody = ["name": "Bob", "email": email.isEmpty ? nil : email] request.httpBody = try? JSONSerialization.data(withJSONObject: jsonBody) uses nil in dictionary literal which is invalid; var jsonBody = ["name": "Bob", "email": email] if !email.isEmpty { jsonBody.removeValue(forKey: "email") } request.httpBody = try? JSONSerialization.data(withJSONObject: jsonBody) uses inverted condition, removing email when it is not empty, incorrect; let jsonBody = ["name": "Bob"] if email != "" { jsonBody["email"] = email } request.httpBody = try? JSONSerialization.data(withJSONObject: jsonBody) tries to mutate immutable dictionary.
  3. Final Answer:

    var jsonBody = ["name": "Bob"]\nif !email.isEmpty {\n jsonBody["email"] = email\n}\nrequest.httpBody = try? JSONSerialization.data(withJSONObject: jsonBody) -> Option D
  4. Quick Check:

    Mutable dict + conditional add = C [OK]
Hint: Use var dictionary and add keys conditionally [OK]
Common Mistakes:
  • Using let dictionary and trying to mutate it
  • Including nil values in dictionary literal
  • Adding then removing keys instead of conditional add
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard