TransloaditKit
TransloaditKit provides file uploading and processing for iOS and macOS apps. This guide uses the
Swift API in TransloaditKit 3.5.0, with TUSKit 3.6.0 in the verified setup below. Earlier
Objective-C releases have different APIs; see the original announcement
for that release history.
Install
CocoaPods
pod 'Transloadit', '3.5.0'
pod 'TUSKit', '3.6.0'
The pod’s dependency range is ~> 3.6.0 (at least 3.6.0, below 3.7.0). Pin TUSKit
explicitly to use the version verified here, and keep Podfile.lock with your project.
Swift Package Manager
Add https://github.com/transloadit/TransloaditKit in Xcode’s package settings with an exact
version of 3.5.0, and select the TransloaditKit library product. This version pins TUSKit to
3.6.0. Keep the resolved dependency versions with your project.
CocoaPods exposes the Transloadit module; Swift Package Manager exposes TransloaditKit.
The conditional import below supports either installation.
Usage
Never put the Auth Secret in an app binary,
Info.plist, or configuration downloaded by the app, including internal apps. Keep it on your
backend and require Signature Authentication for the Workspace or
Template used by the app.
The apiKey:sessionConfiguration:signatureGenerator: initializer accepts a signature without
requiring the Auth Secret. The SDK supplies the exact serialized params string to sign. Your
backend must authenticate the user’s session and authorize the requested upload, allowing only
the expected Auth Key, processing instructions, destinations, and expiry. Reject extra Steps,
arbitrary Templates, fields, and unknown options. A logged-in caller must not be able to use the
backend to sign arbitrary JSON. Apply quotas and upload restrictions on the server; for a
server-owned Template, disable allow_steps_override and allow only that Template.
There are two constraints in this pinned release:
- Assembly creation fixes
auth.expiresat 24 hours in the future. The signing callback cannot replace those parameters. If your server policy requires a shorter expiry, reject the request and use backend Assembly creation or a different Assembly API integration with server-controlled parameters. Do not extend your policy to accommodate the SDK. - The
SignatureCompletionparameter is nonescaping: call it before the signature generator returns. A normal asynchronous HTTP completion cannot capture it. The helper below accepts a synchronous backend transport and must be used off the main thread. That transport must have a finite timeout and throw on failure; the SDK provides no signing timeout or fallback.
Your app supplies requestSignature, its authenticated HTTPS integration with your own backend.
Send the original params string unchanged and the current user session token in the request’s
Authorization header, using a fixed trusted endpoint, rejecting redirects and unsuccessful
HTTP responses. The token belongs to your app’s login system, not to Transloadit. The backend
validates the request and signs the approved original UTF-8 bytes with HMAC-SHA384. It returns
the same params string and a signature, never the Auth Secret. Do not reserialize or change
expiry after approval. Refresh the session before making a new client when it expires.
The complete helper below checks that the backend approved these exact params and supplied a
well-formed signature. Client checks do not replace backend authorization. ApprovedSignature
is this example’s response type, not an SDK type.
import Foundation
#if canImport(TransloaditKit)
import TransloaditKit
#else
import Transloadit
#endif
struct ApprovedSignature {
let params: String
let signature: String
}
enum SigningError: Error {
case missingSession
case notApproved
}
func makeUploadClient(
authKey: String,
userSessionToken: String,
configuration: URLSessionConfiguration = .default,
requestSignature: @escaping (String, String) throws -> ApprovedSignature
) throws -> Transloadit {
guard !userSessionToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
throw SigningError.missingSession
}
return Transloadit(
apiKey: authKey,
sessionConfiguration: configuration,
signatureGenerator: { params, completion in
completion(Result {
let approved = try requestSignature(params, userSessionToken)
let signature = approved.signature
guard approved.params.utf8.elementsEqual(params.utf8),
signature.hasPrefix("sha384:"), signature.count == 103,
signature.dropFirst(7).allSatisfy({ "0123456789abcdef".contains($0) }) else {
throw SigningError.notApproved
}
return signature
})
}
)
}
Create an Assembly
This complete helper creates a resize Step, queues the supplied local files for upload, and
registers a processing-status callback. Include it alongside the client helper above. The backend
policy for this example must allow exactly this 200 × 100 fit resize with result: true.
The upload file count travels outside signed params in this SDK, so it is not an authorization
limit. If your required file restrictions cannot be enforced by the selected workflow, create
the Assembly through your backend instead of issuing a broader signature.
func makeResizeStep() -> Step {
Step(
name: "resize",
robot: "/image/resize",
options: [
"width": 200,
"height": 100,
"resize_strategy": "fit",
"result": true
]
)
}
@discardableResult
func uploadImages(
client: Transloadit,
files: [URL],
created: @escaping (Result<Assembly, TransloaditError>) -> Void,
status: @escaping (Result<AssemblyStatus, TransloaditError>) -> Void
) -> TransloaditPoller {
let poller = client.createAssembly(
steps: [makeResizeStep()], andUpload: files, completion: created
)
poller.pollAssemblyStatus(completion: status)
return poller
}
Pass readable local file URLs from your app’s file selection to uploadImages, and retain the
Transloadit client for the operation. Call it on a background queue because signing is
synchronous; dispatch UI updates from callbacks to the main queue. Handle failure in both
callbacks. A successful created callback means the Assembly exists and uploads were queued,
not that uploading or processing finished. In the status callback, inspect processingStatus:
completed, aborted, and canceled are distinct terminal outcomes.
For file progress and upload errors, implement and retain a TransloaditFileDelegate and assign
it to the client’s weak fileDelegate property. The SDK retains its poller, but app lifecycle,
background execution, cancellation, and resumable file access still need integration and testing
on your target devices. These helpers are not a complete background-upload application.
Documentation
See GitHub for the full documentation.