iOS

Application integration

# iOS + Transloadit

Upload from iOS with TransloaditKit while delegating every request signature to a trusted backend.

Executable recipe

## Build the integration

This Swift example asks a backend to sign requests for one fixed Template, uploads a file, and polls the Assembly status.

1. Add TransloaditKit with Swift Package Manager and create a backend signature endpoint.
2. Require application authentication on the endpoint and sign only the exact string received with the Auth Secret.
3. Initialize the SDK with the signature generator and pass a local file URL to createAssembly.

### Package.swift

```
.package(
    url: "https://github.com/transloadit/TransloaditKit",
    .upToNextMajor(from: "3.0.0")
)
```

### signing-server.ts

```
import { createHmac, timingSafeEqual } from 'node:crypto'
import { createServer } from 'node:http'

const authSecret = process.env.TRANSLOADIT_SECRET
const appApiToken = process.env.APP_API_TOKEN
const templateId = process.env.TRANSLOADIT_TEMPLATE_ID
if (!authSecret || !appApiToken || !templateId) {
  throw new Error('Server configuration is incomplete')
}

createServer(async (request, response) => {
  const expectedToken = Buffer.from(`Bearer ${appApiToken}`)
  const suppliedToken = Buffer.from(request.headers.authorization ?? '')
  const isAuthorized =
    expectedToken.length === suppliedToken.length && timingSafeEqual(expectedToken, suppliedToken)

  if (request.method !== 'POST' || request.url !== '/transloadit/sign') {
    response.writeHead(404).end()
    return
  }
  if (!isAuthorized) {
    response.writeHead(401).end()
    return
  }

  let stringToSign = ''
  for await (const chunk of request) {
    stringToSign += chunk
    if (stringToSign.length > 100_000) {
      response.writeHead(413).end()
      return
    }
  }

  let params: unknown
  try {
    params = JSON.parse(stringToSign)
  } catch {
    response.writeHead(400).end()
    return
  }
  const usesAllowedTemplate =
    typeof params === 'object' &&
    params !== null &&
    !Array.isArray(params) &&
    'template_id' in params &&
    params.template_id === templateId
  if (!usesAllowedTemplate) {
    response.writeHead(403).end()
    return
  }

  const digest = createHmac('sha384', authSecret).update(stringToSign).digest('hex')
  response.writeHead(200, { 'content-type': 'text/plain' }).end(`sha384:${digest}`)
}).listen(3000)
```

### Uploader.swift

```
import Foundation
import TransloaditKit

final class Uploader {
    private let templateId = "YOUR_TRANSLOADIT_TEMPLATE_ID"
    private let transloadit: Transloadit

    init(appSessionToken: String) {
        transloadit = Transloadit(
            apiKey: "YOUR_TRANSLOADIT_KEY",
            sessionConfiguration: .default,
            signatureGenerator: { stringToSign, completion in
                Task {
                    do {
                        var request = URLRequest(
                            url: URL(string: "https://example.com/transloadit/sign")!
                        )
                        request.httpMethod = "POST"
                        request.httpBody = Data(stringToSign.utf8)
                        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
                        request.setValue(
                            "Bearer \(appSessionToken)",
                            forHTTPHeaderField: "Authorization"
                        )

                        let (data, response) = try await URLSession.shared.data(for: request)
                        guard let httpResponse = response as? HTTPURLResponse,
                              httpResponse.statusCode == 200 else {
                            throw URLError(.badServerResponse)
                        }

                        let signature = String(decoding: data, as: UTF8.self)
                        completion(.success(signature))
                    } catch {
                        completion(.failure(error))
                    }
                }
            }
        )
    }

    func upload(fileURL: URL) {
        transloadit.createAssembly(templateId: templateId, andUpload: [fileURL]) { result in
            print(result)
        }.pollAssemblyStatus { result in
            print(result)
        }
    }
}
```

## Authentication

* Initialize TransloaditKit with the public Auth Key and a signatureGenerator that sends each string-to-sign to your authenticated backend.
* The backend signs only permitted requests with the Workspace Auth Secret and returns the prefixed signature. The secret never belongs in the app bundle.
* The signature generator must always call its completion handler with success or failure; otherwise the SDK request remains pending.

## Limitations and operational notes

* An iOS binary cannot keep an Auth Secret. Passing the secret directly to TransloaditKit is suitable only when exposure is an accepted risk.
* The create callback means the Assembly exists and uploads were scheduled; it does not mean file upload or processing has finished.
* Background URL sessions can schedule one task per tus chunk. Tune tusUploadChunkSize for the app’s background-transfer behavior.
* The dependency-free signer uses one server-configured bearer token for a runnable local example. Replace it with expiring per-user session validation and rate limits before production.

## Related Robots

* [/upload/handle](/docs/robots/upload-handle.md)\
  Handle uploads
* [/image/resize](/docs/robots/image-resize.md)\
  Resize images
* [/video/encode](/docs/robots/video-encode.md)\
  Encode video

## Documentation

* [TransloaditKit documentation](/docs/sdks/transloaditkit.md)
* [Transloadit signature authentication](/docs/api/authentication.md)
* [TransloaditKit source and examples⁠](https://github.com/transloadit/TransloaditKit)
* [Apple package dependency documentation⁠](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app)
  [Create a Template](/c/templates/new/)

More integrations

## Continue building your stack

NX

### [Next.js](/integrations/nextjs.md)

Signed Uppy uploads for the Next.js App Router.

LV

### [Laravel](/integrations/laravel.md)

Create Assemblies from Laravel with the official PHP SDK.

PY

### [Python](/integrations/python.md)

Run signed Assembly jobs with the maintained Python SDK.
