iOS
HTTP POST
image upload
text upload
mobile app development

ios Upload Image and Text using HTTP POST

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Uploading an image together with text fields from iOS usually means sending a multipart/form-data HTTP POST request. The key is to build the request body correctly with boundaries, field headers, and binary image data so the server can parse both the text and the file in one request.

Build a Multipart Request

For a form-style upload, the request body must contain:

  • a boundary string
  • one part for each text field
  • one part for the image bytes
  • a closing boundary

Here is a basic Swift example using URLSession:

swift
1import UIKit
2
3func uploadPost(image: UIImage, caption: String) {
4    guard let url = URL(string: "https://example.com/upload"),
5          let imageData = image.jpegData(compressionQuality: 0.8) else {
6        return
7    }
8
9    let boundary = UUID().uuidString
10    var request = URLRequest(url: url)
11    request.httpMethod = "POST"
12    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
13
14    var body = Data()
15
16    body.append("--\(boundary)\r\n".data(using: .utf8)!)
17    body.append("Content-Disposition: form-data; name=\"caption\"\r\n\r\n".data(using: .utf8)!)
18    body.append("\(caption)\r\n".data(using: .utf8)!)
19
20    body.append("--\(boundary)\r\n".data(using: .utf8)!)
21    body.append("Content-Disposition: form-data; name=\"image\"; filename=\"photo.jpg\"\r\n".data(using: .utf8)!)
22    body.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!)
23    body.append(imageData)
24    body.append("\r\n".data(using: .utf8)!)
25
26    body.append("--\(boundary)--\r\n".data(using: .utf8)!)
27
28    URLSession.shared.uploadTask(with: request, from: body) { data, response, error in
29        if let error = error {
30            print("Upload failed:", error)
31            return
32        }
33
34        if let httpResponse = response as? HTTPURLResponse {
35            print("Status:", httpResponse.statusCode)
36        }
37    }.resume()
38}

This pattern works with most servers that expect a standard multipart form upload.

Why Multipart Matters

You cannot just put raw image bytes and plain text next to each other in the body and hope the server guesses the structure. Multipart encoding tells the server:

  • where each field starts
  • which field name it belongs to
  • whether the part is text or file data
  • what filename and content type apply

That is why the boundary string and part headers are so important.

Choose the Right Image Encoding

jpegData(compressionQuality:) is usually a good default for camera photos because it reduces size. If your app needs transparency or exact pixel preservation, PNG may be more appropriate:

swift
guard let pngData = image.pngData() else { return }

The server and the Content-Type header should match the format you send. Do not label PNG bytes as image/jpeg.

Keep Networking and UI Concerns Separate

A practical app structure is:

  • capture or select the image
  • build the multipart request
  • upload with URLSession
  • update the UI only after the completion handler returns

That separation keeps the upload code reusable and makes error handling much cleaner. It also gives you a natural place to add progress reporting, authentication headers, or retry logic later.

If the backend already documents required field names, copy those names exactly. Multipart uploads fail surprisingly often because the client uses "image" while the server expects a different form field such as "photo" or "file".

Common Pitfalls

  • Forgetting the closing boundary or malformed \r\n separators in the multipart body.
  • Sending image data without setting Content-Type to multipart/form-data; boundary=....
  • Labeling the uploaded file with the wrong MIME type.
  • Doing heavy image conversion on the main thread right before upload and making the UI feel stuck.
  • Mixing UI code and request-building code until the upload logic becomes hard to test or reuse.

Summary

  • Uploading image data and text together from iOS usually means a multipart HTTP POST request.
  • Build the body with boundaries, field headers, text parts, and file bytes in the correct order.
  • Use URLSession.uploadTask to send the request.
  • Make sure the file encoding and MIME type match each other.
  • Keep the multipart builder separate from UI code so the upload flow stays maintainable.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.