<!--
{
  "documentType" : "article",
  "framework" : "Foundation",
  "identifier" : "/documentation/Foundation/uploading-data-to-a-website",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Uploading data to a website"
}
-->

# Uploading data to a website

Post data from your app to servers.

## Discussion

Many apps work with servers that accept uploads of files like images or documents, or use web service API endpoints that accept structured data like JSON. To upload data from your app, you use a [`URLSession`](/documentation/Foundation/URLSession) instance to create a [`URLSessionUploadTask`](/documentation/Foundation/URLSessionUploadTask) instance. The upload task uses a [`URLRequest`](/documentation/Foundation/URLRequest) instance that details how the upload is to be performed.

### Prepare your data for upload

The data to upload can be the contents of a file, a stream, or data, as is the case in the following example.

Many web service endpoints take JSON-formatted data, which you create by using the  [`JSONEncoder`](/documentation/Foundation/JSONEncoder) class on <doc://com.apple.documentation/documentation/Swift/Encodable> types like arrays and dictionaries. As shown in the following example, you can declare a structure that conforms to <doc://com.apple.documentation/documentation/Swift/Codable>, create an instance of this type, and use [`JSONEncoder`](/documentation/Foundation/JSONEncoder) to encode the instance to JSON data for upload.

Preparing JSON data for upload

```swift
struct Order: Codable {
    let customerId: String
    let items: [String]
}

// ...

let order = Order(customerId: "12345",
                  items: ["Cheese pizza", "Diet soda"])
guard let uploadData = try? JSONEncoder().encode(order) else {
    return
}
```

There are many other ways to create a data instance, such as encoding an image as JPEG or PNG data, or converting a string to data by using an encoding like UTF-8.

### Configure an upload request

An upload task requires a [`URLRequest`](/documentation/Foundation/URLRequest) instance. As shown in the following example, set the [`httpMethod`](/documentation/Foundation/URLRequest/httpMethod) property of the request to `"``POST``"` or `"PUT"`, depending on what the server supports and expects. Use the [`setValue(_:forHTTPHeaderField:)`](/documentation/Foundation/URLRequest/setValue(_:forHTTPHeaderField:)) method to set the values of any HTTP headers that you want to provide, except the `Content-Length` header. The session figures out content length automatically from the size of your data.

Configuring a URL request

```swift
let url = URL(string: "https://example.com/post")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
```

### Create and start an upload task

To begin an upload, call [`uploadTask(with:from:completionHandler:)`](/documentation/Foundation/URLSession/uploadTask(with:from:completionHandler:)) on a [`URLSession`](/documentation/Foundation/URLSession) instance to create an uploading [`URLSessionTask`](/documentation/Foundation/URLSessionTask) instance, passing in the request and the data instances you’ve previously set up. Because tasks start in a suspended state, you begin the network loading process by calling [`resume()`](/documentation/Foundation/URLSessionTask/resume()) on the task. The following example uses the shared `URLSession` instance, and receives its results in a completion handler. The handler checks for transport and server errors before using any returned data.

Starting an upload task

```swift
let task = URLSession.shared.uploadTask(with: request, from: uploadData) { data, response, error in
    if let error = error {
        print ("error: \(error)")
        return
    }
    guard let response = response as? HTTPURLResponse,
        (200...299).contains(response.statusCode) else {
        print ("server error")
        return
    }
    if let mimeType = response.mimeType,
        mimeType == "application/json",
        let data = data,
        let dataString = String(data: data, encoding: .utf8) {
        print ("got data: \(dataString)")
    }
}
task.resume()
```

### Alternatively, upload by setting a delegate

As an alternative to the completion handler approach, you can instead set a delegate on a session you configure, and then create the upload task with [`uploadTask(with:from:)`](/documentation/Foundation/URLSession/uploadTask(with:from:)). In this scenario, you implement methods from the [`URLSessionDelegate`](/documentation/Foundation/URLSessionDelegate) and [`URLSessionTaskDelegate`](/documentation/Foundation/URLSessionTaskDelegate) protocols. These methods receive the server response and any data or transport errors.

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)